实体框架中的双重自引用

时间:2015-08-11 10:02:35

标签: c# entity-framework

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

  

无法确定类型' WorkFlowState'之间关联的主要结尾。和' WorkFlowState'。必须使用关系流畅API或数据注释显式配置此关联的主要结尾。

代码:

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

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

我该怎么办?

更新1: 人们告诉这个问题是一个重复的问题,但是如果你看一下接受的答案(提供 octavioccl 的第三个选项),你会看到它是如何不同的。

1 个答案:

答案 0 :(得分:3)

问题是EF正试图按惯例配置一对一的关系。如果您在评论中查看@Michael分享的link,您会注意到您需要指定谁是主要目标,谁是依赖结束。当您要创建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);