c# - Entity Framework 中的双重自引用

标签 c# entity-framework

当我尝试创建迁移时, Entity Framework 抛出错误

Unable to determine the principal end of an association between the types 'WorkFlowState' and 'WorkFlowState'. The principal end of this association must be explicitly configured using either the relationship fluent API or data annotations.

代码:

public class WorkFlowState
{
    public Guid Id { get; set; }

    public virtual WorkFlowState NextState { get; set; }
    public virtual WorkFlowState PrevState { get; set; }
}

我应该做什么?

更新1: 人们说这个问题是一种重复的问题,但如果您查看已接受的答案(octavioccl 提供的第三个选项),您会发现它有何不同。

最佳答案

问题是 EF 尝试按照约定配置一对一关系。如果您检查link @Michael 在他的评论中分享了这一点,您会注意到您需要指定谁是主体端,谁是从属端。当您要创建 WorkflowState 的新实例时,您必须始终设置主体端。现在,如果您需要配置一对一关系,您会注意到该链接有两个选项:

选项 1:指定关系的 FK

public class WorkFlowState
{
     public Guid Id { get; set; }

     [Key,ForeignKey("PrevState")]
     public Guid PrevStateId { get; set; }
     public virtual WorkFlowState NextState { get; set; }
     public virtual WorkFlowState PrevState { get; set; }
}

选项 2:使用所需的数据注释:

public class WorkFlowState
{
     public Guid Id { get; set; }

     public virtual WorkFlowState NextState { get; set; }
     [Required]
     public virtual WorkFlowState PrevState { get; set; }
}

但是,如果您需要两个引用作为可选,还有第三个选项:

public class WorkFlowState
{
     public Guid Id { get; set; }

     [ForeignKey("PrevState")]
     public Guid? PrevStateId { get; set; }

     [ForeignKey("NextState")]
     public Guid? NextStateId { get; set; }

     public virtual WorkFlowState NextState { get; set; }
     public virtual WorkFlowState PrevState { get; set; }
}

在本例中,您将创建两个单向关系。为了帮助您更好地了解最后一种情况会发生什么,Fluent Api这些关系的配置将是这样的:

modelBuilder.Entity<WorkFlowState>().HasOptional(t => t.NextState).WithMany().HasForeignKey(t => t.NextStateId);
modelBuilder.Entity<WorkFlowState>().HasOptional(t => t.PrevState).WithMany().HasForeignKey(t => t.PrevStateId);

关于c# - Entity Framework 中的双重自引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31938771/

相关文章:

c# - LINQ 中具有附加值的完整对象投影

c# - Socket 的扩展方法内存泄漏 'ReceiveAsync' !

c# - 停止显示 chromedriver 控制台窗口,Selenium c#

c# - Entity Framework 相关数据外键

linq - 寻求 Entity Framework 中 3 层 LINQ 查询的建议

entity-framework - 如何在 Entity Framework 中添加外键关系?

c# - 如何允许具有管理员权限的用户访问 Controller

entity-framework - 如何在EF Code First CTP5中更改数据库中外键的命名约定?

c# - 模拟一段时间内的高CPU使用率

c# - 如何在列表框中显示替代对象的表示?