EF 6.1 Code First 中与不同主键的一对一关系

Posted

技术标签:

【中文标题】EF 6.1 Code First 中与不同主键的一对一关系【英文标题】:One to One Relationship with Different Primary Key in EF 6.1 Code First 【发布时间】:2017-11-16 22:29:36 【问题描述】:

我在使用 Entity Framework 6.1 从 PayGroup 对象获取对员工对象的引用时遇到问题。我在 PayGroup.SupervisorId -> Employee.EmployeeId 的数据库中有一个外键。请注意,这是零或一对一的关系(一个薪酬组只能有一个主管,一个员工只能是一个薪酬组的主管)。

根据this post on GitHub,在具有不同主键的表上不可能有外键。我已经手动将外键添加到数据库中,但我不知道如何设置流畅的 api 映射以能够从薪酬组获取员工对象。

薪酬组表

员工表

注意:数据库中有一个来自 PayGroup.SupervisorId - Employee.EmployeeId 的外键。

以下是 DTO(我目前没有这些类之间的任何工作关系映射):

public class PayGroup

    public int Id  get; set; 
    public string SupervisorId  get; set; 
    public virtual Employee Supervisor  get; set; 


public class Employee

    public string EmployeeId  get; set; 
    public string FullName  get; set; 

【问题讨论】:

你试试this? 【参考方案1】:

不支持one-to-one 与显式 FK 属性(如您的 PayGroup.SupervisorId)的关系。

所以从模型中删除该属性:

public class PayGroup

    public int Id  get; set; 
    public virtual Employee Supervisor  get; set; 

并使用以下流畅的映射:

modelBuilder.Entity<PayGroup>()
    .HasRequired(e => e.Supervisor)
    .WithOptional()
    .Map(m => m.MapKey("SupervisorId"));

WithOptional() 调用指定了两件事。首先Employee类中没有反向导航属性,其次FK是可选的(表中Allow Nulls = true)。

如果您决定添加反向导航属性

public class Employee

    public string EmployeeId  get; set; 
    public string FullName  get; set; 
    public virtual PayGroup PayGroup  get; set;  // <=

将其更改为WithOptional(e =&gt; e.PayGroup)

如果你想让它成为必需的(表中的Allow Nulls = false),那么使用对应的WithRequiredDependent 重载(Dependent 这里的意思是Employee 将是principal PayGroup 将是依赖)。

【讨论】:

解释清楚就这么简单。我想我被 WithOptional 和 HasRequired 搞砸了。我也在尽力不从 PayGroup 中删除 SupervisorId 字段。谢谢! 好吧,这在某种程度上是可行的。如果在 Pay Group Table 数据库中的“SupervisorId”为 NULL,那么当我使用链接进行查询时,我收到一条错误消息,指出无法将 null 值转换为不可为 null类型。

以上是关于EF 6.1 Code First 中与不同主键的一对一关系的主要内容,如果未能解决你的问题,请参考以下文章

EF,Code First - 如何在插入时设置自定义Guid标识值

EF Code First CTP5 - 使用属性名称作为外键的列名

无法在EF Code First中创建复合主键

如何通过非主键创建一对一关系(EF First Code)

使用共享主键关联时,EF 4.1 Code First 中的级联删除规则

EF Code First 学习笔记:约定配置