2016-01-14 4 views
0

У меня есть этот класс сущностейEF Code First - Определение двухсторонней Navigation Свойства

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 достаточно для определения направления отношения.

Моя цель этой схемы таблицы заключается в том, чтобы эффективно запрашивать, имеет ли узел предыдущий/следующий узел без выполнения операции объединения в своей собственной таблице. И я рад принять компромисс, который должен написать дополнительную логику для поддержания правильности предыдущей/следующей ошибки.

Вот моя проблема:

ЭФ не удается создать такую ​​таблицу со следующей ошибкой:

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

видеть эту ссылку http://www.entityframeworktutorial.net/code-first/inverseproperty-dataannotations-attribute-in-code-first.aspx –

+0

@FrebinFrancis Я пытался следовать инструкциям со следующей конструкцией: общественных class Node { [Key] public int Id {get; частный набор; } public string Имя {get; задавать; } public int PrevId {get; задавать; } public int NextId {get; задавать; } [ForeignKey («PrevId»)] общедоступный виртуальный узел Prev {get; задавать; } [ForeignKey ("NextId")] public virtual Node Next {get; задавать; } } , но я все еще получил ту же ошибку. –

+0

Не могли бы вы показать мне код? Пожалуйста, обновите его в своем вопросе? –

ответ

0

Я не думаю, что вы можете сделать это. Подумайте о перепроектировании схемы таблиц. Предположим, я хочу добавить 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 строки не могут быть вставлены первыми.

Возможно, вы можете удалить ограничение внешнего ключа и управлять отношениями самостоятельно в коде или с помощью процедур хранилища.

+0

В этом случае я сначала вставлю три узла без указания отношений, а затем обновить их во втором раунде. –

+0

@SiuPangTommyChoi Правильно. Вы поняли, что это невозможно сделать в одной вставке. Вот почему я говорю «управляйте отношениями самостоятельно», потому что EF недостаточно умен, чтобы знать «вставить сначала, обновить позже». –

+0

Согласен, я не ожидаю, что EF проверит целостность данных. Как вы думаете, я все еще могу использовать навигационные свойства? –

Смежные вопросы