Как работает отложенная загрузка в предварительной версии EF 8

Как работает отложенная загрузка в предварительной версии EF 8

23 февраля 2023 г.

Среда .NET является лидером отрасли уже более двух десятилетий. В предстоящем выпуске .NET 8 корпорация Майкрософт представляет новые функции и усовершенствования, чтобы упростить процесс разработки для разработчиков .NET.

Предпосылки

  • Базовые знания концепций ООП.
  • Любое знание языков программирования.

Итак, для начала C# и Entity Framework

Цели обучения

Эта статья посвящена некоторым критическим изменениям в предварительной версии EF 8

  • Что такое отложенная загрузка?
  • Что такое запросы без отслеживания?
  • Как установить предварительную версию EF8?
  • Как добавить отложенную загрузку для запросов без отслеживания в предварительной версии EF8?

Начало работы

Entity Framework (EF) — это объектно-реляционный преобразователь (ORM), предоставляющий набор инструментов для работы с базами данных объектно-ориентированным способом. Одной из функций EF является отложенная загрузка, которая позволяет загружать связанные объекты по запросу, а не сразу загружать их все сразу. Ленивая загрузка может повысить производительность и сократить использование памяти за счет загрузки только необходимых данных. В этой статье мы обсудим, как использовать отложенную загрузку для запросов без отслеживания в предварительной версии EF 8 с примерами кода.

Что такое отложенная загрузка?

Отложенная загрузка – это метод, при котором загрузка связанных объектов откладывается до тех пор, пока они не потребуются. В EF это означает, что связанные объекты не загружаются при извлечении основного объекта из базы данных, а загружаются при первом доступе к ним. Это делается путем создания прокси-объекта, представляющего связанный объект, и загрузки фактических данных при доступе к репрезентативному объекту.

Ленивая загрузка может быть полезна при работе с большими наборами данных, поскольку она позволяет загружать только необходимые данные, а не все данные одновременно. Это может уменьшить объем используемой памяти и повысить производительность.

Что такое запросы без отслеживания?

В Entity Framework (EF) "запрос без отслеживания" — это запрос, извлекающий данные из базы данных без отслеживания каких-либо изменений в возвращаемых объектах.

Когда EF извлекает данные из базы данных, он по умолчанию создает отслеживаемые объекты. EF отслеживает любые изменения, внесенные в эти объекты, такие как их добавление, обновление или удаление. Он может автоматически генерировать операторы SQL для сохранения этих изменений в базе данных, когда это необходимо.

Однако в некоторых сценариях вам может не понадобиться отслеживать изменения возвращаемых сущностей. Например, при извлечении больших объемов данных, которые не будут изменены, отслеживание сущностей может быть ненужным накладным расходом, который может замедлить выполнение запроса и потреблять больше памяти. В таких случаях вы можете использовать запросы без отслеживания для извлечения данных без создания отслеживаемых объектов.

Чтобы создать запрос без отслеживания, вы можете использовать метод AsNoTracking для DbSet. Вот пример:

using (var context = new MyContext())
{
    var customers = context.Customers.AsNoTracking().ToList();
}

Как установить предварительную версию EF 8?

Чтобы установить предварительную версию EF 8, выполните следующие действия:

  1. Откройте Visual Studio 2019 или более позднюю версию и создайте новый проект .NET Core или .NET Framework.
  2. Щелкните правой кнопкой мыши проект в обозревателе решений и выберите "Управление пакетами NuGet".
  3. На вкладке "Обзор" найдите "Microsoft.EntityFrameworkCore" и выберите его в результатах поиска.
  4. Установите флажок «Включить предварительную версию» и выберите из раскрывающегося списка версию EF 8, которую вы хотите установить.
  5. Нажмите кнопку «Установить», чтобы установить предварительную версию EF 8.

Кроме того, вы также можете использовать консоль диспетчера пакетов для установки предварительной версии EF 8. Вот как:

  1. Откройте консоль диспетчера пакетов, выбрав «Инструменты > Диспетчер пакетов NuGet > Консоль диспетчера пакетов» из меню Visual Studio.
  2. В консоли диспетчера пакетов введите следующую команду, чтобы установить предварительную версию EF 8:
Install-Package Microsoft.EntityFrameworkCore -Version 8.0.0-preview.1.23111.4 -Pre

Нажмите Enter, чтобы выполнить команду. Пакет будет установлен в вашем проекте.

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

Реализовать ленивую загрузку в EF 8

EF 8 — это последняя версия Entity Framework, которая в настоящее время находится в предварительной версии. Он представляет несколько новых функций и улучшений, в том числе улучшения отложенной загрузки. В EF 8 отложенная загрузка включена по умолчанию для всех свойств навигации, что означает, что связанные объекты будут загружаться по запросу при доступе.

Однако отложенная загрузка не включена по умолчанию при использовании запросов без отслеживания, которые не отслеживают изменения, внесенные в объекты. Это связано с тем, что запросы без отслеживания не создают прокси-объекты, необходимые для отложенной загрузки. Чтобы включить отложенную загрузку для запросов без отслеживания в EF 8, необходимо включить ее с помощью явного метода UseLazyLoadingProxies().

Ниже приведен пример использования отложенной загрузки с запросами без отслеживания в EF 8:

using Microsoft.EntityFrameworkCore;

public class MyContext : DbContext
{
    public DbSet<Order> Orders { get; set; }
    public DbSet<Customer> Customers { get; set; }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseLazyLoadingProxies().UseSqlServer("connectionString");
    }
}

public class Order
{
    public int OrderId { get; set; }
    public int CustomerId { get; set; }
    public virtual Customer Customer { get; set; }
}

public class Customer
{
    public int CustomerId { get; set; }
    public string Name { get; set; }
    public virtual ICollection<Order> Orders { get; set; }
}

В этом примере у нас есть класс MyContext, который наследуется от DbContext и определяет два DbSet для Order и Клиент. Метод OnConfiguring переопределяется для настройки подключения к базе данных и включения отложенной загрузки прокси-серверов с помощью метода UseLazyLoadingProxies().

Класс Order имеет свойство CustomerId, которое является внешним ключом для класса Customer, и свойство Customer свойство, помеченное как виртуальное, чтобы включить отложенную загрузку. Класс Customer имеет коллекцию объектов Order, которые также помечены как виртуальные, чтобы разрешить отложенную загрузку.

Теперь давайте посмотрим, как на практике использовать отложенную загрузку с запросами без отслеживания. Предположим, мы хотим получить список клиентов и связанных с ними заказов, но нам нужно только прочитать данные и намерены оставить их неизменными. Мы можем использовать метод AsNoTracking(), чтобы отключить отслеживание изменений, повысить производительность и получить доступ к связанным заказам с помощью отложенной загрузки.

var customers = context.Customers
.Include(c => c.Orders)
.AsNoTracking()
.ToList();

foreach (var customer in customers)
{
  Console.WriteLine(customer.Name);
  foreach (var order in customer.Orders)
  {
    Console.WriteLine(" " + order.OrderId);
  }
}

В этом коде мы используем метод Include для быстрой загрузки связанных объектов Order для каждого клиента, а затем используем метод AsNoTracking для отключения отслеживания изменений. Затем мы перебираем клиентов и их заказы, используя отложенную загрузку.

Обратите внимание, что отложенная загрузка может вызвать проблемы с производительностью при неправильном использовании. Циклический доступ к связанным сущностям может привести к выполнению большого количества запросов к базе данных, что может быть медленным. Чтобы избежать этого, вы можете использовать метод "Включить" для быстрой загрузки связанных объектов в одном запросе или использовать метод "Загрузить" для явной загрузки связанных объектов.

Заключение

Отложенная загрузка — это полезный метод загрузки связанных объектов по требованию, а не загрузки их всех одновременно. В EF 8 отложенная загрузка включена по умолчанию для всех свойств навигации, но не включена по умолчанию для запросов без отслеживания. Чтобы разрешить ленивую загрузку для запросов без отслеживания, вы должны явно включить ее с помощью метода `UseLazyLoadingProxies()`. Однако лучше использовать отложенную загрузку с осторожностью, чтобы избежать проблем с производительностью, и в некоторых случаях рассмотреть возможность использования упреждающей или явной загрузки.


Также опубликовано здесь


Оригинал