web-dev-qa-db-fra.com

Comment faire fonctionner le chargement paresseux avec EF Core 2.1.0 et les proxys

J'ai les modèles suivants:

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; }
}

qui sont enregistrés dans DbContext en tant que:

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");
}

J'essaie d'utiliser le chargement paresseux avec Microsoft.EntityFrameworkCore.Proxies Comme décrit ici :

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

    var opts = optionsBuilder.Options;

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

J'interroge des sessions en utilisant context.All<Session>. Cependant, Session.User Et Session.User.Organization Sont nuls par défaut. Pour les charger, je dois faire quelque chose comme context.All<Session>().Include(s => s.User).Include(s => s.User.Organization). Comment puis-je éviter cela? Pourquoi UseLazyLoadingProxies ne fonctionne-t-il pas?


  • Version .NET Core: 2.1.300-preview2-008533
  • Cible: netcoreapp2.1
  • Version EF Core (et proxy): 2.1.0-preview2-final
13
KolesnichenkoDS

Étapes pour configurer le chargement différé avec des proxys dans Asp.net Core 2.1

  1. Installez le package Microsoft.EntityFrameworkCore.Proxies
  2. Activer LazyLoadingProxies Vous pouvez l'activer avec un appel à UseLazyLoadingProxies:
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .UseLazyLoadingProxies()
        .UseSqlServer(myConnectionString);

Ou lorsque vous utilisez AddDbContext:

.AddDbContext<BloggingContext>(
b => b.UseLazyLoadingProxies()
      .UseSqlServer(myConnectionString));
  1. EF Core activera ensuite le chargement différé pour toute propriété de navigation qui peut être remplacée, c'est-à-dire qu'elle doit être virtuelle.
11
Johar Zaman

Vous pouvez essayer de configurer des proxys dans Startup.cs comme

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

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

    #endregion Database configuration
}

Et en passant, vous pouvez déjà mettre à jour vos packages d'application vers la version 2.1.0 pure (non finale ou RC). L'une des raisons pour lesquelles votre configuration peut ne pas fonctionner est une version instable des composants.

NB: Microsoft.EntityFrameworkCore.Proxies.dll est installé à partir de nuget indépendamment d'EFCore

8
Artem Fomin

J'ai résolu cela en définissant la sérialisation JSON en service comme cette réponse https://stackoverflow.com/a/49350457/4178475

0
Mosta