实体框架中的双重自引用 [英] Double self referencing in Entity Framework

查看:55
本文介绍了实体框架中的双重自引用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试创建迁移时,实体框架会引发错误

When I'm trying to create a migration, Entity Framework throws an error

无法确定类型'WorkFlowState'和'WorkFlowState'之间的关联的主要终点.必须使用关系流利的API或数据注释显式配置此关联的主要端.

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 提供的第三个选项),您会发现它与众不同.

Update 1: People are telling that the question is kind of duplicated question, but if you look at the accepted answer ( the third option which octavioccl provided ) you will see how it is different.

推荐答案

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

The problem is EF is trying to configure by convention an one-to-one relationship. If you check the link that was shared by @Michael in his comment, you will notice that you need to specify who is the principal end and who is the dependent end. When you are going to create a new instance of WorkflowState you must set always the principal end. Now, if you need to configure an one to one relationship, you will notice by that link you have two options:

选项1:指定您的恋人关系

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; }
}

但是如果您需要两个引用均为可选,则还有第三种选择:

But there is a third option in case you need both references as optional:

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

In this case you are going to create two unidirectional relationships. For help you understand better what happens in this last case, the Fluent Api configurations of these relationships would be this way:

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

这篇关于实体框架中的双重自引用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆