Популярный пример: в системе отслеживания проблем JIRA проблемы могут быть связаны с другими проблемами.К самой ссылке прикреплены некоторые данные, в частности тип.
Пример:
Выпуск A -> зависит от -> Выпуск B Выпуск B <- <em>зависит от <- <strong>Выпуск A
Мы вводим такие же отношения для сущности в нашем C #Приложение ASP.NET MVC, использующее EF 4.1 CodeFirst, и мне интересно, как лучше всего смоделировать это отношение?
Подробности :
В этой ситуации есть некоторые особенности:
- К ссылке прикреплены некоторые данные, поэтому мы не можем просто смоделировать отношения «многие ко многим» между проблемами и проблемами.Скорее, нам нужно ввести новую сущность Ссылка , которая представляет связь между двумя проблемами.
- Ссылка, по определению, связывает два экземпляра одной и той же сущности,это отношение «два ко многим» (ссылка имеет две проблемы, проблема может иметь много ссылок).
- Ссылка направлена, что означает, что если проблема A зависит от проблемы B, то проблема B зависит от проблемы A.
У нас наверняка будет сущность Link , которая выглядит следующим образом:
public class Link
{
public int ID { get; set; }
public Issue IssueA { get; set; }
public Issue IssueB { get; set; }
public LinkType Type { get; set; }
}
Класс Issue может выглядеть следующим образом:
public class Issue
{
public int ID { get; set; }
public virtual ICollection<Link> Links { get; set; }
}
В настоящее время существуетбыть только один тип ссылки: зависимость.Итак, тип ссылки будет выглядеть следующим образом:
public class LinkType
{
public int ID { get; set; }
public string ForwardName { get; set; } // depends on
public string BackwardName { get; set; } // is depended on by
}
Теперь большой вопрос:
Если я хочу, чтобы EF автоматически управлял Issue.Links
, у меня естьсказать ему, какой внешний ключ в таблице Link
использовать.Либо я использую IssueA
, либо я использую IssueB
.Я не могу использовать оба, могу ли я?
Либо я определяю:
modelBuilder.Entity<Issue>().HasMany(i => i.Links).WithRequired(l => l.IssueA);
, либо я определяю:
modelBuilder.Entity<Issue>().HasMany(i => i.Links).WithRequired(l => l.IssueB);
Возможные подходы - Мне любопытно ваше мнение о том, могут ли некоторые из них привести к проблемам, не могут быть реализованы или какой-либо из этих подходов может рассматриваться как «наилучшая практика»:
- Добавьте дваКоллекции к Выпуск ,
ICollection<Link> OutgoingLinks
, ICollection<Link> IncomingLinks
.Таким образом, EF может поддерживать коллекции, но с точки зрения бизнес-логики они не имеют особого смысла. - Добавьте только одну коллекцию и настройте EF 4.1 для добавления входящих и исходящие ссылки на него, если это возможно.
Добавьте только одну коллекцию и реализуйте ее самостоятельно:
ICollection<Link> AllLinks { return _context.Links.Where(l => l.IssueA == this || l.IssueB == this).ToList(); }
Проблема с этим подходомв том, что объект домена выполняет задачи доступа к данным, что плохо с точки зрения разделения проблем.
Любое другое?