Вам следует избегать использования такого подхода, поскольку пользователь будет загружен одним DbContext, а его заказы будут связаны с другим удаленным контекстом.Когда вы переходите к обновлению пользователя, вы сталкиваетесь с ошибками или дублирующимися заказами, или с грязной задачей повторной привязки заказа (и других дочерних объектов) к контекстам перед сохранением.В будущем, несомненно, возникнет путаница, если заказы будут сопоставлены пользователям, и кто-то пойдет и напишет код в .Include(x => x.Orders)
Если вы полностью отсоедините связанные сущности от EF и будете полагаться на нагрузку по требованию, вы потеряете многие возможности, которые EFдает вам.
Подобные проблемы, как правило, возникают из-за смешения области действия / продолжительности жизни сущностей с областью контекста, из которой они загружены.Например, загрузка сущностей в одном методе с помощью DbContext, их возврат, а затем решение, что вы хотите получить доступ к связанным сущностям, но DbContext был удален.Самый простой метод, который я могу порекомендовать использовать, - это принятие моделей представления POCO и обеспечение того, чтобы объекты никогда не выходили за пределы своего DbContext, а только модели представления.Таким образом, вы можете создать структуру модели представления для представления необходимых вам данных, а затем использовать сущности и их ссылки для заполнения этих моделей представления, используя .Select()
, не беспокоясь о отложенной загрузке или нетерпеливой загрузке.
Например:
using (var context = new StoreContext())
{
var userViewModel = context.Users.Where(x => x.UserId == userId)
.Select(x => new UserViewModel
{
UserId = x.UserId,
UserName = x.UserName,
Orders = x.Orders
.Where(o => o.IsActive)
.Select( o => new OrderViewModel
{
OrderId = o.OrderId,
OrderNumber = o.OrderNumber
Price = o.OrderItems.Sum(i => i.Price)
}).ToList()
}).SingleOrDefault();
return userViewModel;
}
Automapper может помочь с отображением объектов для просмотра моделей.Это не карта древовидной структуры "один-к-одному", а скорее выравнивание модели представления для представления данных, которые необходимы представлению, а затем заполнение их структурой объекта.Вам просто нужно быть немного осторожным, чтобы извлекать только данные и поддерживаемые агрегатные методы из сущностей, потому что они будут передаваться в SQL, поэтому в .Select нет .Net или пользовательских функций.Пусть модели представлений принимают необработанные значения и предоставляют альтернативные свойства для выполнения форматирования или используют .Select()
для извлечения анонимных типов, заставляют EF материализовать их в экземпляры POCO с помощью .ToList()
/ .Single()
/ и т. Д.а затем заполните свои модели представлений теми, которые используют Linq2Object.
Работа с объектами по требованию и просмотр моделей / DTO для перемещения данных позволяет избежать проблем с объектами.Если все сделано правильно, EF может извлечь эти данные очень быстро и избежать ошибок, связанных с производительностью, таких как отключение из-за отложенных нагрузок во время сериализации.Это означает, что когда вы закончите работу с моделью представления, вам потребуется перезагрузить объект, чтобы применить изменения.Может показаться, что имеет больше смысла просто использовать сущности, а затем EF волшебным образом присоединить их и сохранить изменения, но ваша модель представления будет иметь всю информацию, необходимую для быстрого извлечения этой сущности по ID, если это необходимо, и вам нужно будет рассмотреть случаигде данные могли измениться между временем, когда вы впервые получили объект, и временем, когда вы готовы его изменить.