Рейтинговые книги
Читем онлайн Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 420 421 422 423 424 425 426 427 428 ... 642

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() может отрицательно повлиять на производительность. Для решения проблемы в EF Core 5 были введены разделяемые запросы. Вместо выполнения одиночного запроса исполняющая среда EF Core будет разделять запрос LINQ на несколько запросов SQL и затем объединять все связанные данные. Скажем, добавив к запросу LINQ вызов AsSplitQuery(), можно ожидать, что предыдущий запрос будет представлен в виде множества запросов SQL:

var query = Context.Makes.<b>AsSplitQuery()</b>

  .Include(x =&gt; x.Cars.Where(x=&gt;x.Color == &quot;Yellow&quot;)).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() либо Мах()).

(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})

В следующих примерах показано, как получить связанные данные о производителе и заказах для записи Car:

// Получить запись Car.

var car = Context.Cars.First(x =&gt; x.Id == 1);

// Получить информацию о производителе.

Context.Entry(car).Reference(c =&gt; c.MakeNavigation).Load();

// Получить заказы, к которым относится данная запись Car.

Context.Entry(car).Collection(c =&gt; 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 во все запросы LINQ для определенной сущности. Например, распространенное проектное решение для баз данных предусматривает использование "мягкого" удаления вместо "жесткого". В таблицу добавляется поле, указывающее состояние удаления записи. Если запись "удалена", то значение поля устанавливается в true (или 1), но запись из базы данных не убирается. Прием называется "мягким" удалением. Чтобы отфильтровать записи, повергнувшиеся "мягкому" удалению, от тех, которые обрабатывались нормальными операциями, каждая конструкция where обязана проверять значение поля с состоянием удаления записи. Включение такого фильтра в каждый запрос может занять много времени, да и не забыть о нем довольно проблематично.

Инфраструктура EF Core позволяет добавлять к сущности глобальный фильтр запросов, который затем применяется к каждому запросу, вовлекающему эту сущность. Для описанного выше примера с "мягким" удалением вы устанавливаете фильтр на сущностном классе, чтобы исключить записи, повергнувшиеся "мягкому" удалению. К любым создаваемым EF Core запросам, затрагивающим сущности с глобальными фильтрами запросов, будут применяться их фильтры. Вам больше не придется помнить о необходимости включения конструкции where в каждый запрос.

1 ... 420 421 422 423 424 425 426 427 428 ... 642
На этой странице вы можете бесплатно читать книгу Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю бесплатно.
Похожие на Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю книги

Оставить комментарий