Razbezhkin
@Razbezhkin
программист, преподаватель

Как в EntityFramework настроить отношения между таблицами, которые ссылаются друг на друга по внешнему ключу?

Здравствуйте!
Есть две таблицы в БД, для которых созданы в коде два класса:
public class ForumTopic
{
        [Key, DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
        public int TopicId { get; set; }
        public int LastMessageId { get; set; }
        [ForeignKey("LastMessageId")]
        public virtual ForumMessage LastMessage { get; set; }
}

public class ForumMessage
{
        [Key, DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
        public int MessageID { get; set; }
        public int TopicID { get; set; }
        [ForeignKey("TopicID")]
        public virtual ForumTopic Topic { get; set; }
}


На первый взгляд, структура содержит ссылки друг на друга и не понятно, какая таблица - главная, а какая подчиненная.

Поясню смысл: Есть тема форума (ForumTopic), у которой есть множество сообщений(ForumMessage), это отношение задается полем [ForeignKey("TopicID")] public virtual ForumTopic Topic { get; set; }. А у темы форума есть ссылка на последнее сообщение темы, которое задается полями LastMessageId и LastMessage. (избыточность добавлена для увеличения производительности при формировании списка тем с указанием какое сообщение было последним)

При попытке что-то извлечь из контекста EF получаю ошибку:

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

Очевидно, что EF "думает", что у меня кросс-ссылки друг на друга и это ему не нравиться (хотя SQL запросы прекрасно отрабатывают с такой структурой), как все же настроить контекст EF, чтобы он, EF работал без ошибок.

Спасибо.
  • Вопрос задан
  • 133 просмотра
Решения вопроса 1
Razbezhkin
@Razbezhkin Автор вопроса
программист, преподаватель
Спасибо Толстый Лорри, за подсказку.
Действительно, без указания ссылки на коллекцию записей в дочерней таблице в виде вот такого свойства:

public virtual ICollection Messages { get; set; }

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

в результате структура классов стала вот такой:

public class ForumTopic
{
        [Key, DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
        public int TopicId { get; set; }
        public int LastMessageId { get; set; }
        [ForeignKey("LastMessageId")]
        public virtual ForumMessage LastMessage { get; set; }
        [InverseProperty("Topic")]
        public virtual ICollection<ForumMessage> Messages { get; set; }
}

public class ForumMessage
{
        [Key, DatabaseGenerated(System.ComponentModel.DataAnnotations.Schema.DatabaseGeneratedOption.Identity)]
        public int MessageID { get; set; }
        public int TopicID { get; set; }
        [ForeignKey("TopicID")]
        public virtual ForumTopic Topic { get; set; }
}
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы