EF 代码优先 - 定义双向导航属性

EF Code First - Define Two-Way Navigation Properties

我有这个实体class

public class Node
{
    [Key]
    public int Id { get; private set; }
    public string Name { get; set; }
    public virtual Node Prev { get; set; }
    public virtual Node Next { get; set; }
}

一个节点总是有 0 或 1 个前一个节点和 0 或 1 个下一个节点。

我希望 EF 生成以下 table 架构

Id | Name | Prev_Id | Next_Id

您很快就会注意到,Next_Id 是多余的,因为 Prev_Id 足以定义方向关系。

我这个table模式的目的是有效地查询一个节点是否有前一个/下一个节点,而不用自己做连接操作table。而且我很高兴采取权衡,我必须编写额外的逻辑来维护 prev/next id 的正确性。

这是我的问题:

EF 无法创建这样的 table,出现以下错误:

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

我想知道 EF 是否允许这样的设计以及如何允许。

更新

我改成这个,还是报同样的错误

public class Node
{
    [Key]
    public int Id { get; private set; }
    public string Name { get; set; }
    public int PrevId { get; set; }
    public int NextId { get; set; }
    [ForeignKey("PrevId")]
    public virtual Node Prev { get; set; }
    [ForeignKey("NextId")]
    public virtual Node Next { get; set; }
}

我认为你做不到。考虑 re-design 您的 table 模式。假设我想添加 3 个新节点,如下所示:

var first = new Node { Name = "first" };
var second = new Node { Name = "second" };
var third = new Node { Name = "third" };

first.Next = second;
second.Prev = first;
second.Next = third;
third.Prev = second;

---- expected table data ----
Id       Name         PrevId        NextId
1        first         NULL           2
2        second         1             3
3        third          2            NULL

现在你告诉我应该先插入哪一行。如果首先插入 id=1 行,则会破坏外键约束,因为 NextId=2 不存在。同样id=2 & id=3行不能先插入。

也许您可以删除外键约束并在代码中自己管理关系,或者使用存储过程。