简体   繁体   English

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

[英]EF Code First - Define Two-Way Navigation Properties

I have this entity 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; }
}

A node will always have 0 or 1 previous node and 0 or 1 next node. 一个节点将始终具有0或1个上一个节点以及0或1个下一个节点。

And I would like EF to generate the following table schema 我希望EF生成以下表架构

Id | Name | Prev_Id | Next_Id

As you will soon notice that, Next_Id is redundant since Prev_Id is sufficient to define the directional relationship. 您将很快注意到, Next_Id是多余的,因为Prev_Id足以定义方向关系。

My purpose of this table schema is to efficiently query whether a node has a previous / next node without doing a join operation on its own table. 该表架构的目的是在不对自己的表执行联接操作的情况下,有效地查询节点是否具有上一个/下一个节点。 And I am happy to take the trade-off that I have to write extra logic to maintain the prev/next id correctness. 我很高兴做出权衡,即我必须编写额外的逻辑来维护prev / next id的正确性。

Here is my problem: 这是我的问题:

The EF fails to create such table with the following error: EF无法创建此类表,并出现以下错误:

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. 必须使用关系流利的API或数据注释显式配置此关联的主要端。

I wonder if EF allows such design and how. 我想知道EF是否允许这种设计以及如何进行。

UPDATES 更新

I change to this and still got the same error 我更改为此,仍然遇到相同的错误

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

I don't think you can do this. 我认为您无法做到这一点。 Consider re-design your table schema. 考虑重新设计表架构。 Let's say I want to add 3 new nodes like following: 假设我要添加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

Now you tell me which row should be inserted first. 现在,您告诉我应该首先插入哪一行。 If the id=1 row is inserted first, it breaks the foreign key constraint because NextId=2 doesn't exist. 如果首先插入id = 1行,则它将打破外键约束,因为NextId = 2不存在。 Similarly id=2 & id=3 rows can't be inserted first. 同样,不能先插入id = 2&id = 3行。

Maybe you can remove the foreign key constraint and manage the relationship by yourself in the code, or using store procedures. 也许您可以在代码中或使用存储过程自己删除外键约束并管理关系。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM