首页 > 解决方案 > EF Core 中从现有实体的多级继承

问题描述

我在 EF 核心代码优先方法中有以下模型结构。

public abstract class  BaseModel
{
    [Key]
    public string Id { get; set; }
    public DateTime LastUpdatedDate { get; set; }
}


public class Company  :BaseModel
{
     
    public string Name { get; set; }
    public string Address { get; set; }
}

public class CompanyLog :Company
{
     
    public string LogId { get; set; }
    public DateTime LogDate { get; set; }
}

and DB Context is
public class MyDbContext : DbContext
{
     public DbSet<Company> Company { get; set; }
     public DbSet<CompanyLog> CompanyLog { get; set; }
}

但是在数据库迁移之后,CompanyLog 表只使用自己的属性创建,而不是基表属性。我怎样才能做到这一点?db迁移后,数据库表结构预期为

CREATE TABLE dbo."Company"
(
    Id text  NOT NULL,
    LastUpdatedDate TimeStamp, 
    Name text, 
    Address text, 
)
CREATE TABLE dbo."CompanyLog"
(
    Id text  NOT NULL,
    LastUpdatedDate TimeStamp, 
    Name text, 
    Address text, 
    LogId text   NULL,
    LogDate TimeStamp,  
)

标签: c#entity-framework-core

解决方案


CompanyLog 表仅使用其自己的属性创建,但不使用基表属性

这是因为 EF Core 考虑CompanyCompanyLog成为数据库继承的一部分,因此实现了其中一种受支持的策略(当前为TPH (Table-per-hierarchy)并从 EF Core 5.0 开始,TPT (Table-per-type))。

事实上,它在帖子中的显示方式(即没有额外的数据注释和/或流畅的配置)我得到了一个带有鉴别器列的表,它是 TPH 的实现。可能你有一些额外的东西给你 TPT - 两个表,“基础”保存基本属性,“派生”只保存附加属性。

您需要的是 TPC(每类表)或根本没有数据库继承。前者暂不支持,后者可以通过如下流畅的配置实现(目前还没有数据注解):

modelBuilder.Entity<CompanyLog>().HasBaseType((Type)null);

推荐阅读