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

本文关键字:导航 属性 定义 代码 EF | 更新日期: 2023-09-27 18:30:22

我有这个实体类

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生成以下表架构

Id | Name | Prev_Id | Next_Id

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

我使用此表

架构的目的是有效地查询节点是否具有上一个/下一个节点,而无需对其自己的表执行连接操作。我很乐意权衡我必须编写额外的逻辑来保持上一个/下一个 id 的正确性。

这是我的问题:

EF 无法创建此类表,并显示以下错误:

无法确定类型"节点"和"节点"之间关联的主端。必须使用关系流畅 API 或数据注释显式配置此关联的主体端。

我想知道 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; }
}

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

我认为你不能这样做。请考虑重新设计表架构。假设我想添加 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 行不能先插入。

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