EF: Должен ли я включать идентификаторы внешнего ключа в мои объекты?

1

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

По достоинству оценят мысли от Pro.

Без внешних ключей

public class ProductGroup
{
    public int ProductGroupID { get; set; }
    public string Name { get; set; }

    //Navigation Properties
    public virtual System_ProductGroup System_ProductGroup { get; set; }
    public virtual ICollection<ProductSubGroup> ProductSubGroups { get; set; }
    public virtual ProductSection ProductSection { get; set; }
    public virtual ICollection<GeneralTranslation> GeneralDescriptionTranslations { get; set; }
}

С внешними ключами

public class ProductGroup
{
    public int ProductGroupID { get; set; }
    public string Name { get; set; }

    //Foreign Keys
    public int System_ProductGroupID { get; set; }
    public int ProductSectionID { get; set; }

    //Navigation Properties
    public virtual System_ProductGroup System_ProductGroup { get; set; }
    public virtual ICollection<ProductSubGroup> ProductSubGroups { get; set; }
    public virtual ProductSection ProductSection { get; set; }
    public virtual ICollection<GeneralTranslation> GeneralDescriptionTranslations { get; set; }
}
Теги:
entity-framework

3 ответа

1
Лучший ответ

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

В конце дня внешние ключи предназначены для связывания вас с другими объектами, и, как вы сказали, они больше представляют собой конструкцию базы данных. Как разработчик, вы знаете, в каком столбце находится внешний ключ в virtual объекте, и вы можете получить доступ к этому свойству соответственно, поэтому исключение внешних ключей из вашего объекта POCO не приведет к исключению вашего доступа к этим данным.

Точка @HiperiX (в его комментарии), устраняя внешний ключ, сама по себе, избавит вас от ленивой нагрузки. Если вы собираетесь выполнять определенную логику с ключами, которые определят, следует ли захватить ссылочный объект, то включение внешних ключей было бы хорошей идеей. Я обновил формулировку своего сообщения, чтобы отразить это предостережение.

  • 0
    Не уверен, что понимаю, как исключение включения прямого внешнего ключа может помешать моей способности выполнять отложенную загрузку ... разве отложенная загрузка все еще будет доступна при использовании виртуального ключевого слова и включенной отложенной загрузки в контексте?
  • 1
    Возможно, я объяснил это плохо, но я пытался понять, что единственный способ получить значение внешнего ключа - получить сущность, на которую он ссылается, а затем получить свойство та сущность, которая соответствует ключу. Таким образом, если вы хотите отфильтровать набор virtual сущностей до тех, у которых есть определенные значения для столбца, на который ссылается ваш внешний ключ, вы должны будете получить все virtual сущности ДО того, как получите значение, по которому вы фильтруете. Таким образом, вы не будете лениво загружать эту virtual сущность.
Показать ещё 2 комментария
1

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

1

Обычно стараюсь избегать. Понятие внешнего ключа относится к реляционной БД, то есть к уровню настойчивости. И даже с POCO, предназначенным для использования в качестве DAO, я предпочитаю удалять ненужные напоминания о базовой технологии.

Но есть случай, когда я нашел их полезными: когда вы хотите, чтобы SomeCollection.Remove(x) удалял также в базе данных.

В этом случае с EF вы должны создать для собираемого объекта составной PK, включая FK. Поэтому в этом случае вам нужен FK в вашем POCO.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню