При использовании Entity Framework я должен установить свойство навигации или свойство внешнего ключа, при установке FK? - PullRequest
0 голосов
/ 21 февраля 2020

У меня есть некоторый код, который выглядит следующим образом:

var customer = dbcontext.Customers.Find(1);

var order = new Order();
order.CustomerId = customer.Id;

dbcontext.Orders.Add(order);
dbcontext.SaveChanges();

Лучше ли это делать или установить отношение, установив свойство навигации:

var customer = dbcontext.Customers.Find(1);

var order = new Order();
order.Customer = customer; //Set navigation prop as opposed to FK field

dbcontext.Orders.Add(order);    
dbcontext.SaveChanges();

Какой подход рассматривается Лучшая практика или предпочтительнее?

Ответы [ 3 ]

0 голосов
/ 21 февраля 2020

Моя рекомендация заключается в том, что объекты должны предоставлять свойства навигации или внешние ключи, но не оба одновременно. Если вы используете свойство навигации, используйте свойства тени (EF Core) для FK.

Причина в том, что Updates и гарантируют, что объект всегда в завершенном состоянии. Когда у вас есть оба, EF не синхронизирует c их до тех пор, пока не будет вызван SaveChanges(). Это может привести к ошибкам, если код, ожидающий одно или другое, вызывается между обновлением и SaveChanges(). (Проверочные вызовы и т. Д. c.) Т.е. вы устанавливаете FK, но затем какой-то код проверяет свойство Nav.

В большинстве случаев я предпочитаю навигационные свойства, но для ссылок я использую FK, которые на самом деле никогда не используются необходимо загрузить (помимо удовлетворения целостности данных), например, ключи Constants / Enum, или в случаях, когда мне нужна максимальная производительность для чего-то вроде операций массового обновления.

0 голосов
/ 21 февраля 2020

Вы беспокоитесь о производительности?

A) Нет: если это не так, вам не следует беспокоиться об этом и всегда использовать навигационные свойства для удобства чтения.

B) Да: тогда вам следует запросить у клиента .Select(c => c.id) для начала и все еще использовать только свойства навигации. В этом случае ясно, что вы не будете обновлять никакое другое поле Customer, потому что вы сравниваете его только с настройкой FK.

var customer = dbcontext.Customers
                        .Find(1)
                        .Select(b => new Customer { Id = b.Id } );

var order = new Order();
order.Customer = customer; //Set navigation prop as opposed to FK field

dbcontext.Orders.Add(order);    
dbcontext.SaveChanges();

C) Да, очень сильно: в этом упрощенном примере Вы дали, бессмысленно запрашивать Customer с его PK, чтобы затем использовать только PK. У вас уже есть вся необходимая информация, вы могли бы установить ее непосредственно в Order. Однако нам придется прикрепить его вручную, иначе efcore попытается создать уже существующий Customer.

var order = new Order();
order.Customer = new Customer { Id = 1 };
dbcontext.Attach<Customer>(order.Customer); 

dbcontext.Orders.Add(order);    
dbcontext.SaveChanges();
0 голосов
/ 21 февраля 2020

Если вашему коду необходим объект customer для дальнейших операций, оба способа в порядке, прокси-серверы EF позаботятся обо всем.

В противном случае, установив FK, вы можете избежать запросов к базе данных Customers для получения информации о клиенте. , повышая эффективность работы (у вас уже есть идентификатор клиента). Я обычно предпочитаю этот способ.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...