Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю
var query = Context.Makes
.Include(x => x.Cars.Where(x=>x.Color == "Yellow")).ToList();
В результате запустится следующий запрос:
SELECT [m].[Id], [m].[Name], [m].[TimeStamp], [t].[Id], [t].[Color],
[t].[MakeId], [t].[PetName], [t].[TimeStamp]
FROM [dbo].[Makes] AS [m]
LEFT JOIN (
SELECT [i].[Id], [i].[Color], [i].[MakeId], [i].[PetName], [i].[TimeStamp]
FROM [Dbo].[Inventory] AS [i]
WHERE [i].[Color] = N'Yellow') AS [t] ON [m].[Id] = [t].[MakeId]
ORDER BY [m].[Id], [t].[Id]
Энергичная загрузка с разделением запросов
Наличие в запросе LINQ множества вызовов
Include()
AsSplitQuery()
var query = Context.Makes.<b>AsSplitQuery()</b>
.Include(x => x.Cars.Where(x=>x.Color == "Yellow")).ToList();
Вот как выглядят выполняемые запросы:
SELECT [m].[Id], [m].[Name], [m].[TimeStamp]
FROM [dbo].[Makes] AS [m]
ORDER BY [m].[Id]
SELECT [t].[Id], [t].[Color], [t].[MakeId], [t].[PetName],
[t].[TimeStamp], [m].[Id]
FROM [dbo].[Makes] AS [m]
INNER JOIN (
SELECT [i].[Id], [i].[Color], [i].[MakeId], [i].[PetName], [i].[TimeStamp]
FROM [Dbo].[Inventory] AS [i]
WHERE [i].[Color] = N'Yellow'
) AS [t] ON [m].[Id] = [t].[MakeId]
ORDER BY [m].[Id]
Применению разделяемых запросов присущ и недостаток: если данные изменяются между выполнением запросов, тогда возвращаемые данные будут несогласованными.
Явная загрузка
Явная загрузка — это загрузка данных по навигационному свойству после того, как главный объект уже загружен. Такой процесс включает в себя дополнительное обращение к базе данных для получения связанных данных. Прием может быть удобен, если приложению необходимо получать связанные записи выборочно на основе какого-то действия пользователя, а не извлекать все связанные записи.
Процесс начинается с уже загруженной сущности и использования метода
Entry()
DbContext
Make
Reference()
Collection()
Load()
ToList()
Count()
Мах()
В следующих примерах показано, как получить связанные данные о производителе и заказах для записи
Car
// Получить запись Car.
var car = Context.Cars.First(x => x.Id == 1);
// Получить информацию о производителе.
Context.Entry(car).Reference(c => c.MakeNavigation).Load();
// Получить заказы, к которым относится данная запись Car.
Context.Entry(car).Collection(c => c.Orders).Query().
IgnoreQueryFilters().Load();
Ленивая загрузка
Ленивая загрузка представляет собой загрузку записи по требованию, когда навигационное свойство применяется для доступа к связанной записи, которая пока еще не загружена в память. Ленивая загрузка — это средство EF 6, снова добавленное в версию EF Core 2.1. Хотя включение ленивой загрузки кажется разумной идеей, временами она может стать причиной возникновения проблем с производительностью в вашем приложении из-за потенциально лишних циклов взаимодействия с базой данных. В результате по умолчанию ленивая загрузка в EF Core отключена (в EF 6 она была включена).
Ленивая загрузка может быть полезна в приложениях интеллектуальных клиентов (WPF, Windows Forms), но в веб-приложениях и службах использовать ее не рекомендуется, так что в книге она не рассматривается. За дополнительными сведениями о ленивой загрузке и ее применением с EF Core обращайтесь в документацию по ссылке
https://docs.microsoft.com/ru-ru/ef/core/querying/related-data/lazy
Глобальные фильтры запросов
Глобальные фильтры запросов позволяют добавлять конструкцию
where
true
1
where
Инфраструктура EF Core позволяет добавлять к сущности глобальный фильтр запросов, который затем применяется к каждому запросу, вовлекающему эту сущность. Для описанного выше примера с "мягким" удалением вы устанавливаете фильтр на сущностном классе, чтобы исключить записи, повергнувшиеся "мягкому" удалению. К любым создаваемым EF Core запросам, затрагивающим сущности с глобальными фильтрами запросов, будут применяться их фильтры. Вам больше не придется помнить о необходимости включения конструкции
where