使用 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");
}
}
这最终产生了正确的映射:
我想将两个派生的 类 映射到两个 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");
}
}
这最终产生了正确的映射: