首页 文章

EF Core Fluent API配置阻止TPC继承

提问于
浏览 1352
1

我有相互继承的模型,但我很难让流畅的api配置按照我的意愿行事 . 假设我有一个基类来定义一些核心属性

public class Entity
{
   public int Id { get; set; }
   public string Title { get; set };
}

还有Book的子类

public class Book : Entity
{
    public int Edition { get; set; }
}

通过这种方式,我可以拥有书籍,杂志,小册子,漫画,演讲等,都可以从我的实体继承,而不必在每个 class 上定义关系 .

现在我将DbSets添加到DbContext中

public class ApplicationDbContext : DbContext
{
   public virtual DbSet<Book> Books { get; set; }
   public virtual DbSet<Magazine> Magazines { get; set; }
   public virtual DbSet<Comic> Comics { get; set; }
}

最后我添加了迁移初始化 .

我的迁移现在为每种类型创建单独的表(TPC) . 完善 .

当我尝试使用流畅的API配置我的基类时出现问题 .

我为Entity添加了一个配置

class EntityConfiguration : IEntityTypeConfiguration<Entity>
{
    public void Configure(EntityTypeBuilder<Entity> builder)
    {
       builder.HasKey(e => e.Id);
       builder.Property(e => e.Title).IsRequired();
    }
}

我的想法是,我现在只需要配置基本实体,子类的所有表都应该选择配置 .

我将配置添加到DbContext OnModelCreating方法 .

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
   base.OnModelCreating(modelBuilder);
   modelBuilder.ApplyConfiguration(new EntityConfiguration());
}

当我添加迁移时,我最终得到了这个

migrationBuilder.CreateTable(
                name: "Entity",
                columns: table => new
                {
                    Edition = table.Column<int>(nullable: true),
                    Name = table.Column<string>(nullable: true),
                    Id = table.Column<int>(nullable: false)
                        .Annotation("SqlServer:ValueGenerationStrategy", SqlServerValueGenerationStrategy.IdentityColumn),
                    Discriminator = table.Column<string>(nullable: false),
                    Title = table.Column<string>(nullable: false),
                    Frequency = table.Column<int>(nullable: true)
                },
                constraints: table =>
                {
                    table.PrimaryKey("PK_Entity", x => x.Id);
                });

通过尝试配置基类,EF现在沿着TPH路由向下,并使用鉴别器列为Entity创建单个表 .

有没有办法避免这种情况?甚至可以配置基类并让所有具体表获取基类的配置,但是为子类创建表?

注意:我已尝试直接在DbContext OnModelCreating方法中配置实体,而不是使用单独的配置类,但这行为完全相同 .

EF Core文档实际上说不支持TPC,这很奇怪,因为它确实为子类创建了单独的表,直到我尝试配置基类 .

我曾尝试使用Ignore()来抑制TPH,但这没有任何效果 .

给出的示例不是现实世界 . 我的实际项目有更多的类,它们都有共同的属性和关系,所以我想避免不得不一遍又一遍地配置相同的东西 .

1 回答

  • 1

    你说 EF Core 在编写时不支持TPC是正确的 .

    但是,似乎有办法解决这个问题(至少生成'Up'脚本) .

    删除 FluentAPI 注册并在Entity类的属性上使用 Annotations

    public abstract class Entity
    {
        [Key]
        public int Id { get; set; }
        [Required]
        public string Title { get; set; }
    }
    

    另外,因为TPC是Table Per(Concrete)类,所以's good practice to make the class you'重新继承自 abstract .

相关问题