使用 TPT 的 EF 继承 - 如何指定外键列名称?

EF inheritance with TPT - how to specify the foreign key column name?

我想将两个派生的 类 映射到两个 table (TPT)

[Table("User")]
public class User
{
    public int Id { get; set; }
    public string Name { get; set; }
}

[Table("Employee")]
public class Employee : User
{
    public int UserId { get; set; }
    public string DeptName { get; set; }
}

tables 已经存在(即我不能修改架构)并且定义如下:

注意 table Employee 中的 UserId 列既是其 PK 又是对 table User 的 FK,列Id.

DbContext 尽可能直接 - 没有定义流畅的映射。

public class TestInheritContext : DbContext
{
    public DbSet<User> Users { get; set; }
}

尝试访问 Users 集合时,出现以下 EF 异常:

System.Data.SqlClient.SqlException: 列名无效 'Id'.

显然,它试图从 table Employee.

中读取列 Id

我见过的所有 TPT 示例在所有 table 中都使用相同的 PK 列名称。例如,this one.

我该如何解决?

想通了。

首先,为了对此进行调试,查看 EF 在幕后创建的实际映射很有帮助。

我安装了 EF Power Tools VS 扩展,r-clicked 上下文文件,

Entity Framework -> View Entity Data Model

得到这个:

注意实体 Employee 有自己的 UserId 属性 继承的 Id 属性 .

所以我做的第一件事就是从派生的 class:

中删除 UserId 属性
[Table("Employee")]
public class Employee : User
{
    // not needed
    //public int UserId { get; set; } 

    public string DeptName { get; set; }
}

但这还不够。我现在有来自基础 class 的 Id 属性,它必须指向两个不同名称的列,具体取决于它来自哪个 table/entity:

对于 User:Id => Id
对于 Employee:Id => UserId

我无法为此使用属性,所以我将使用流畅的语法。

对于 User 实体,我 没有 做任何事情,因为列名称与 属性 名称匹配。

对于Employee实体我必须干预:

public class TestInheritContext : DbContext
{
    public DbSet<User> Users { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Employee>()
            .Property(e => e.Id)
            .HasColumnName("UserId");
    }
}

这最终产生了正确的映射: