代码之家  ›  专栏  ›  技术社区  ›  user246392

如何以比现在更有效的方式将数据库列映射到EF模型属性

  •  1
  • user246392  · 技术社区  · 7 年前

    我有一个可空的 varchar(max) Guid? 先输入EF代码。但是,该属性实际上位于许多其他实体派生自的基类中。

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Model1>().Property(e => e.Property1).HasConversion(p => p.ToString(), p => (Guid?)Guid.Parse(p));
    }
    

    3 回复  |  直到 7 年前
        1
  •  2
  •   Ivan Stoev    7 年前

    当然有可能。由于缺少自定义约定,因此通过“典型”实现 modelBuilder.Model.GetEntityTypes()

    var entityTypes = modelBuilder.Model.GetEntityTypes()
        .Where(t => t.ClrType.IsSubclassOf(typeof(BaseClass)));
    
    var valueConverter = new ValueConverter<Guid, string>(
        v => v.ToString(), v => (Guid?)Guid.Parse(v));
    
    foreach (var entityType in entityTypes)
        entityType.FindProperty(nameof(BaseClass.Property1)).SetValueConverter(valueConverter);
    

    您也可以考虑使用框外提供的EF核心。 Guid String 转换器:

    var valueConverter = new GuidToStringConverter();
    
        2
  •  0
  •   Sergey Shulik    7 年前

    最好进行下一次计算属性:

    [Column("Property1")]
    public string Property1Raw { get; set; }
    
    [IgnoreDataMember]
    public Guid? Property1
    {
        get => Guid.TryParse(Property1AsString, out Guid result) ? result : (Guid?)null;
        set => Property1Raw = value?.ToString();
    }
    
        3
  •  0
  •   sellotape    7 年前

    另一种方法是有一个匹配的基类 IEntityTypeConfiguration

    internal class EntityConfiguration<T> : IEntityTypeConfiguration<T> where T : Entity
    {
        public virtual void Configure(EntityTypeBuilder<T> builder)
        {
            builder.Property(e => e.Property1).HasConversion(p => p.ToString(), p => (Guid?)Guid.Parse(p));
            // ... Other base-specific config here
        }
    }
    

    (假设这里调用了基类 Entity -根据需要进行更改)。

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.ApplyConfiguration(new Model1EntityConfiguration());
        modelBuilder.ApplyConfiguration(new Model2EntityConfiguration());
        // ...
    }
    

    ...

    internal sealed class Model1EntityConfiguration : EntityConfiguration<Model1>
    {
        public override void Configure(EntityTypeBuilder<Model1> builder)
        {
            base.Configure(builder); // <-- here's the key bit
            // ...; e.g.
            builder.Property(c => c.Name).HasMaxLength(80).IsRequired();
        }
    }