Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Disable all lazy loading or force eager loading for a LINQ context

I have a document generator which contains queries for about 200 items at the moment but will likely be upwards of 500 when complete. I've recently noticed that some of the mappings denote lazy loading. This presents a problem for the document generator as it needs access to all of these properties based on which document is being generated.

While I am aware of the DataLoadOptions that can be specified to the context, this would result in me having to explicitly specify every column that could possibly be loaded. That is north of 1000 as it all of the data fetching takes place in one context.

Is there any way for me to disable lazy loading for a context or explicitly enable eager loading to ignore the defer loading property? Perhaps extending the DB context class and overriding something?

like image 607
Jake Wharton Avatar asked Aug 02 '10 13:08

Jake Wharton


People also ask

How can you disable lazy loading for all entities?

We can disable lazy loading for a particular entity or a context. To turn off lazy loading for a particular property, do not make it virtual. To turn off lazy loading for all entities in the context, set its configuration property to false.

What is lazy loading and eager loading in Linq?

Lazy loading in Entity Framework is the default phenomenon that happens for loading and accessing the related entities. However, eager loading is referred to the practice of force-loading all these relations.

How do I get rid of lazy loading?

To disable lazy loading on a specific post or page, open the post or page, and in the “Cache Options” meta box, un-check the “LazyLoad for images” option. Don't forget to publish or update the post or page to save your changes.

How do I turn off eager loading in Entity Framework?

In EF Core: context. ChangeTracker. LazyLoadingEnabled = false; Per this answer.


2 Answers

You will need to set DeferredLoadingEnabled, and then include every property using some reflection like:

DataLoadOptions dataLoadOptions = new DataLoadOptions();

foreach (PropertyInfo pi in typeof(SomeThingyClass).GetProperties())
{
    ParameterExpression paramExp = Expression.Parameter(typeof(SomeThingyClass), "s");
    Expression expr = Expression.Convert(Expression.Property(paramExp, pi.Name), typeof(object));
    LambdaExpression lambda = Expression.Lambda(expr, paramExp);
    dataLoadOptions.LoadWith((Expression<Func<SomeThingyClass, object>>) lambda);
}
like image 128
Jan Jongboom Avatar answered Oct 08 '22 11:10

Jan Jongboom


This is tricky with LINQ to SQL. The short answer is, it depends.

If your entities are laid out in a manner such that you have a relationship that mirrors this:

Customers -> Orders -> OrderDetails

And you need to evaluate properties on all 3 entities in order to make a decision, your best bet is to go with writing a join. Using .LoadWith will fetch Customers and Orders using a single statement, but then will issue a query for every single OrderDetails record as well.

So, even if you did specify every child relationship with LoadWith, you're not going to get a single query issued to retrieve the result.

like image 24
Marc Avatar answered Oct 08 '22 11:10

Marc