Как заставить ленивую загрузку работать с EF Core 2.1.0 и прокси

У меня есть следующие модели:

public class Session
{
    public int SessionID { get; set; }
    public int UserID { get; set; }

    public virtual User User { get; set; }
}

public class User
{
    public int UserID { get; set; }
    public int OrganizationID { get; set; }

    public virtual ICollection<Session> Sessions { get; set; }
    public virtual Organization Organization { get; set; }
}

public class Organization
{
    public int OrganizationID { get; set; }

    public virtual ICollection<User> Users { get; set; }
}

которые зарегистрированы в DbContext как:

modelBuilder.Entity<Session>(entity =>
{
    entity.ToTable("sessions");

    entity.Property(e => e.SessionID).HasColumnName("id");
    entity.Property(e => e.UserID).HasColumnName("user_id");

    entity.HasOne(e => e.User)
        .WithMany(e => e.Sessions)
        .HasForeignKey(e => e.UserID);
}

modelBuilder.Entity<User>(entity =>
{
    entity.ToTable("users");

    entity.Property(e => e.UserID).HasColumnName("id");
    entity.Property(e => e.OrganizationID).HasColumnName("organization_id");

    entity.HasOne(e => e.Organization)
        .WithMany(e => e.Users)
        .HasForeignKey(e => e.OrganizationID);
}

modelBuilder.Entity<Organization>(entity =>
{
    entity.ToTable("organizations");

    entity.Property(e => e.OrganizationID).HasColumnName("id");
}

Я пытаюсь использовать ленивую загрузку с Microsoft.EntityFrameworkCore.Proxies, как описано здесь:

builder.Register(c =>
{
    var optionsBuilder = new DbContextOptionsBuilder<Context>();
    optionsBuilder
        .UseLazyLoadingProxies()
        /* more options */
        ;

    var opts = optionsBuilder.Options;

    return new Context(opts);
}).As<DbContext>().InstancePerLifetimeScope();

Я запрашиваю сеансы с помощью context.All<Session>. Однако Session.User и Session.User.Organization по умолчанию равны нулю. Чтобы загрузить их, мне нужно сделать что-то вроде context.All<Session>().Include(s => s.User).Include(s => s.User.Organization). Как мне этого избежать? Почему не работает UseLazyLoadingProxies?


  • Версия .NET Core: 2.1.300-preview2-008533
  • Цель: netcoreapp2.1
  • Версия EF Core (и прокси): 2.1.0-preview2-final

Вам довелось найти решение? Имея ту же проблему

Tom D. 03.06.2018 19:57

Если честно, а ленивая загрузка действительно нужна? Я пробовал это с полным EF и нашел это не очень полезным, поскольку он работает только до тех пор, пока у вас есть ваш контекст, поэтому, если вы хотите просто получить всю информацию, вам все равно придется вручную загружать все свойства или поддерживать контекст. Я создал методы расширения для DbSets, такие как BuildSession, BuldUser, которые содержат все, что мне нужно.

Krzysztof Skowronek 06.06.2018 14:59
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
17
2
14 482
3

Ответы 3

Вы можете попробовать настроить прокси в Startup.cs, например

public void ConfigureServices(IServiceCollection services)
{
    #region Database configuration

    // Database configuration
    services.AddDbContext<DbContext>(options =>
        options.UseLazyLoadingProxies()
            .UseSqlServer(Configuration.GetConnectionString("MyConnectionString")));

    #endregion Database configuration
}

И, кстати, вы уже можете обновить свои пакеты приложений до чистой версии 2.1.0 (не финальной или RC). Одна из причин, по которой ваша конфигурация может не работать, - нестабильная версия компонентов.

NB: Microsoft.EntityFrameworkCore.Proxies.dll устанавливается из nuget независимо от EFCore

Шаги по настройке отложенной загрузки с прокси в Asp.net Core 2.1

  1. Установите пакет Microsoft.EntityFrameworkCore.Proxies
  2. Включить LazyLoadingProxies Вы можете включить его с помощью вызова UseLazyLoadingProxies:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .UseLazyLoadingProxies()
        .UseSqlServer(myConnectionString);

Или при использовании AddDbContext:

.AddDbContext<BloggingContext>(
b => b.UseLazyLoadingProxies()
      .UseSqlServer(myConnectionString));
  1. Затем EF Core включит отложенную загрузку для любого свойства навигации, которое можно переопределить, то есть оно должно быть виртуальным.

Я решил это, установив сериализацию JSON в сервисе, как этот ответ https://stackoverflow.com/a/49350457/4178475

Другие вопросы по теме