Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EF Core enable Lazy Loading conditionally

I am looking for a possible way to enable Lazy Loading in my DbContext but not all the time, only in specific instances when I need it. Because of issues like the N+1 queries with large datasets and JSON serialization traversing object properties and serializing my entire database I usually do not want Lazy Loading. However, in some instances I do want it. When generating reports I load a top-level object and many child objects in order to populate the report fields. Due to the nature of the schema this would need 30 or more Include() and ThenInclude() calls without Lazy Loading.

Is there a way to enable Lazy Loading conditionally when doing a query? I tried using 2 DbContexts, with one extending the other and enabling Lazy Loading, like this:

public class MyLazyContext : MyContext
{
    public MyLazyContext(DbContextOptions<MyLazyContext> options) : base(options) { }

    protected override OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseLazyLoadingProxies();
    }
}

And injecting them separately as dependencies. The constructor had a problem with passing DbContextOptions<MyLazyContext> to the base constructor requiring DbContextOptions<MyContext> so I changed them both to DbContextOptions<MyContext>. While this worked in my web application, my unit tests were broken due to how my generic class activators worked for DbContext - this got me thinking that this approach was code smell so I started looking for a better solution.

like image 902
Valuator Avatar asked Aug 14 '18 19:08

Valuator


1 Answers

You can use ChangeTracker.LazyLoadingEnabled property:

Gets or sets a value indicating whether navigation properties for tracked entities will be loaded on first access.

The default value is true.

e.g.

context.ChangeTracker.LazyLoadingEnabled = false;
var query = context.Set<…>()...;
like image 169
Ivan Stoev Avatar answered Nov 20 '22 08:11

Ivan Stoev