EF Core Fluent API配置阻止TPC继承 [英] EF Core Fluent API Configuration Prevents TPC Inheritance

查看:150
本文介绍了EF Core Fluent API配置阻止TPC继承的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有彼此继承的模型,但是我正在努力使流利的api配置按我希望的方式运行。假设我有一个定义一些核心属性的基类

I have models which inherit from each other, but I am struggling to get the fluent api configuration to behave as I want it to. Let's say I have a base class which defines some core properties

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

以及Book的子类

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

这样我就可以拥有书籍,杂志,小册子,漫画,演讲等,都是从Entity继承而来,不必在每个类上都定义关系。

This way I can have books, magazines, pamphlets, comics, speeches etc, all inheriting from my Entity, and not have to define the relationship on every class.

现在,我将这样的DbSet添加到DbContext中

Now I add my DbSets to the DbContext like this

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; }
}

最后我添加了Initial迁移。

And finally I add-migration Initial.

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

My migration now creates separate tables (TPC) for each type. Perfect.

问题是当我尝试使用流利的API配置基类时出现的。

The problem comes when I try to configure my base class using fluent API.

我添加了一个实体的配置

I add a configuration for Entity

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

我现在只需要配置基本实体,所有子类的表都应选择配置。

The idea being that I will now only need to configure the base Entity, and all tables for the subclasses should pick up the configuration.

我将配置添加到DbContext OnModelCreating方法中。

I add my configuration to the DbContext OnModelCreating method.

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

添加迁移后,我最终会得到这个

When I add-migration, I end up with this

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路线运行,并创建了一个

By trying to configure the base class, EF is now going down the TPH route, and creating a single table for Entity with a discriminator column.

有没有办法避免这种情况?

Is there a way to avoid this? Is it even possible to configure the base class and have all concrete tables pick up the configuration on the base class but create tables for the subclasses?

注意:我已经尝试过配置基类,并让所有具体表接受基类上的配置,但为子类创建表吗?实体直接在DbContext OnModelCreating方法中,而不是使用单独的配置类,但这的行为是相同的。

NOTE: I have tried configuring the Entity directly in the DbContext OnModelCreating method, instead of using a separate configuration class, but this behaves just the same.

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

The EF Core docs actually say TPC is not supported, which is strange because it does create separate tables for the subclasses until I try to configure the base class.

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

I have tried using Ignore() to suppress the TPH but this has no effect.

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

Example given is not real-world. My actual project has many more classes which all have common properties and relationships, so I want to avoid having to configure the same things over and over again.

推荐答案

您的正确说法是 EF Core 在撰写本文时不支持TPC。

You are correct in saying that EF Core does not support TPC as of writing.

但是,确实有一种解决方法(至少用于生成 Up脚本)。

However, there does appear to be a way to get around this (for generating the 'Up' script at least).

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

Remove the FluentAPI registrations and use Annotations on the Entity class's properties:

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

此外,由于TPC是每(具体)表类,因此这是一个好习惯使您要从抽象继承的类。

Also, because TPC is Table Per (Concrete) Class, it's good practice to make the class you're inheriting from abstract.

这篇关于EF Core Fluent API配置阻止TPC继承的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆