C# EF Core Fluent API配置防止TPC继承

C# EF Core Fluent API配置防止TPC继承,c#,asp.net-core,.net-core,entity-framework-core,asp.net-core-2.0,C#,Asp.net Core,.net Core,Entity Framework Core,Asp.net Core 2.0,我有一些相互继承的模型,但我正在努力使fluentapi配置按我所希望的方式运行。假设我有一个基类,它定义了一些核心属性 public class Entity { public int Id { get; set; } public string Title { get; set }; } 和Book的一个子类 public class Book : Entity { public int Edition { get; set; } } 通过这种方式,我可以拥有书籍、杂

我有一些相互继承的模型,但我正在努力使fluentapi配置按我所希望的方式运行。假设我有一个基类,它定义了一些核心属性

public class Entity
{
   public int Id { get; set; }
   public string Title { get; set };
}
和Book的一个子类

public class Book : Entity
{
    public int Edition { get; set; }
}
通过这种方式,我可以拥有书籍、杂志、小册子、漫画、演讲等,这些都是从我的实体继承而来的,而不必在每个类上定义关系

现在我将我的dbset添加到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; }
}
当我添加迁移时,我的结果是

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);
                });
migrationBuilder.CreateTable(
名称:“实体”,
列:表=>new
{
版本=表.列(可空:真),
Name=table.Column(可空:true),
Id=table.Column(可空:false)
.Annotation(“SqlServer:ValueGenerationStrategy”,SqlServerValueGenerationStrategy.IdentityColumn),
鉴别器=表.列(可空:false),
Title=table.Column(可空:false),
频率=table.Column(可为空:true)
},
约束:表=>
{
表.PrimaryKey(“PK_实体”,x=>x.Id);
});
通过尝试配置基类,EF现在正沿着TPH路线前进,并使用鉴别器列为实体创建一个表

有没有办法避免这种情况?甚至可以配置基类,让所有具体的表在基类上选择配置,但为子类创建表吗

注意:我尝试过直接在DbContext OnModelCreating方法中配置实体,而不是使用单独的配置类,但其行为与此相同

EF Core文档实际上说TPC不受支持,这很奇怪,因为在我尝试配置基类之前,它确实会为子类创建单独的表

我尝试使用Ignore()来抑制TPH,但没有效果


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

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

然而,似乎有一种方法可以解决这个问题(至少可以生成“Up”脚本)

删除
FluentAPI
注册,并在实体类的属性上使用
Annotations

public abstract class Entity
{
    [Key]
    public int Id { get; set; }
    [Required]
    public string Title { get; set; }
}
另外,由于TPC是每个(具体的)类的表,因此最好将继承自
的类抽象化


我总是以这种方式使用TPC模式。 首先,我将“实体”标记为抽象。 EntityConfiguration.cs

    public class EntityConfiguration<T> : IEntityTypeConfiguration<T> where T : Entity
    {
        public virtual void Configure(EntityTypeBuilder<T> builder)
        {
            builder.HasKey(e => e.Id);
            builder.Property(e => e.Title).IsRequired();
        }
    }
public class BookConfiguration : EntityConfiguration<Book>
{
    public override void Configure(EntityTypeBuilder<Book> builder)
    {
        base.Configure(builder);

        builder.ToTable("book");
        builder.Property(b => b.Edition).HasColumnName("edition");
    }
}
公共类EntityConfiguration:EntityTypeConfiguration其中T:Entity
{
公共虚拟空间配置(EntityTypeBuilder)
{
builder.HasKey(e=>e.Id);
builder.Property(e=>e.Title).IsRequired();
}
}
BookConfiguration.cs

    public class EntityConfiguration<T> : IEntityTypeConfiguration<T> where T : Entity
    {
        public virtual void Configure(EntityTypeBuilder<T> builder)
        {
            builder.HasKey(e => e.Id);
            builder.Property(e => e.Title).IsRequired();
        }
    }
public class BookConfiguration : EntityConfiguration<Book>
{
    public override void Configure(EntityTypeBuilder<Book> builder)
    {
        base.Configure(builder);

        builder.ToTable("book");
        builder.Property(b => b.Edition).HasColumnName("edition");
    }
}
公共类书籍配置:EntityConfiguration
{
公共覆盖无效配置(EntityTypeBuilder)
{
配置(生成器);
建筑商。可折叠(“账簿”);
builder.Property(b=>b.Edition).HasColumnName(“Edition”);
}
}

使用这种方法,EF core只会创建“book”表,而不使用任何鉴别器。

Hi@Toby,这成功了吗?Hi@StevePadmore谢谢你的回答。不幸的是,我需要在我的模型类中避免任何类型的注释,所以这条途径是不开放的。我确实找到了一种方法来做我想做的事情,通过滚动我自己的映射类而不是使用内置配置。我将写下我所做的,并添加一个答案,以防其他人有同样的问题。谢谢:)嘿,托比,你介意分享一下你对第一期的看法吗?但这不是TPC。TPC允许在一条语句中查询所有派生类型,EF将找出如何生成联接。@GertArnold感谢您的解释。无论如何,我认为作者的目标是定义一个基类,并且只需指定一次它的配置,派生类应该选择这个配置