Ef core fluent api设置所有列类型的接口

时间:2017-08-29 15:30:39

标签: c# entity-framework .net-core entity-framework-core ef-fluent-api

不幸的是,ef核心不支持TPC模式,但我们需要这种行为。我写了一个名为IBase的接口,每个实体都实现了这个接口:

public interface IBase
{
    Guid Id { get; set; }

    [Column(TypeName = "datetime2")]
    DateTime CreateDate { get; set; }

    [Required]
    [StringLength(255)]
    string CreateUser { get; set; }

    bool Deleted { get; set; }
}

我想摆脱注释以使用Fluent API配置。但是我有大约20个不同的实体和7个Base-Values,我不想一遍又一遍地做出相同的配置:

 modelBuilder.Entity<SomeEntity>()
            .Property(e => e.CreateDate)
            .HasColumnType("datetime2(2)")
            .IsRequired();

如何为实施IBase的所有实体配置每个Base-Property一次?

2 个答案:

答案 0 :(得分:8)

EF核心完全没有基类/继承,因此只需创建一个基类泛型类并将常用内容放入其中,然后从这些基类继承模型:

public abstract class BaseModel<TId>
{
    TId Id { get; set; }

    [Column(TypeName = "datetime2")]
    DateTime CreateDate { get; set; }

    [Required]
    [StringLength(255)]
    string CreateUser { get; set; }

    bool Deleted { get; set; }
}

class Model : BaseModel<Guid>{ ... //model specific stuff }

如果出于某种原因,使用fluentapi比使用名为IEntityTypeConfiguration<TModel>的配置接口更为重要,您需要的只是创建基本配置,后者继承特定配置。然后在DbContext.OnModelCreating方法中应用这些配置,就像那样:

class BaseConfiguration<TBaseModel> : IEntityTypeConfiguration<TBaseModel>
{
    public virtual void Configure(EntityTypeBuilder<TBaseModel> builder)
    {
        builder.Property...
    }
}

class ModelConfiguration : BaseConfiguration<Model>
{
    public override void Configure(EntityTypeBuilder<Model> builder)
    {
         base.Configure(builder)
         ...// model specific stuff
    }
}

class CustomDbContext : DbContext
{
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        modelBuilder.ApplyConfiguration(new ModelConfiguration());
    }
}

答案 1 :(得分:1)

此解决方案适用于实体框架而非核心:

        modelBuilder.Types<BaseModel>().Configure((configuration) =>
        {
            configuration.Property(p => p.CreateUser)
                .HasMaxLength(250)
                .IsRequired();
        });