Eager , Lazy and explicit loading in EF6
If this small resume is true ?
Yes.
If it is true, what is the difference between eager and explicit loading?
Eager loading is the opposite of Lazy loading but Explicit loading is similar to lazy loading, except that: you explicitly retrieve the related data in code; it doesn't happen automatically when you access a navigation property. You load related data manually by getting the object state manager entry for an entity and calling the Collection.Load
method for collections or the Reference.Load
method for properties that hold a single entity.
From techblog:
Eager Loading :
Eager loading is the opposite of Lazy loading which is : The process
of loading a specific set of related objects along with the objects
that were explicitly requested in the query.Explicit Loading :
Explicit loading is defined as : when objects are returned by a query,
related objects are not loaded at the same time. By default, they are
not loaded until explicitly requested using the Load method on a
navigation property.
And:
If I Use lazy loading and I call for example
dpc_gestion.dpc_participant
, does the navigation properties loads?or I will get an exception?
You don't get any exception and the navigation properties should loads.
Is there a case when eager loading or explicit loading were better
than lazy loading in performance and responsiveness?
Eager loading is typically more efficient when you need the related data for all retrieved rows of the primary table. And also when relations are not too much, eager loading will be good practice to reduce further queries on server. But when you know that you will not need a property instantly then lazy loading maybe a good choice. And also eager loading is a good choice in a situation where your db context would be disposed and lazy loading could not take place anymore. For example consider the following:
public List<Auction> GetAuctions()
{
using (DataContext db = new DataContext())
{
return db.Auctions.ToList();
}
}
After calling this method, You cannot load the related entity lazily because the db
is disposed and so the Eager Loading would be a better choice here.
One more thing to note is: Lazy loading will produce several SQL request while Eager loading load data with one request. Eager loading is also a good choice to solve the n+1 selects issue in ORMs.
Have a look at this post: What is the n+1 selects issue?
differences between Eager Loading and Explicit Loading
Eager loading loads related entities as part of the query, i.e. the enties are loaded when the query is actually executed. This is the opposite of lazy loading where the related entities are loaded when you access them through a navigation property.
Calling Load()
explicitly loads the entities on your request instead of waiting for you to access the navigation properties. It's for example useful when the initial query doesn't return any related entities (because you didn't use eager loading) and you have disabled lazy loading for whatever reason.
Combining lazy and eager loading in EF
Yes you can do that.And it's a Good practise too according to the real situation like yours.
When you don't need the Lazyloding
,on that particular method you can disable it as shown below.
public List<PropertyListDto> SearchProperties(AdditionalSearchInput input)
{
_context.Configuration.LazyLoadingEnabled = false;//to remove lazy loading
///your code
}
Note : In Entity Framework 4 and beyond Lazy Loading is enabled by default. We can disable
it globally, on DbContext
level, or selectively, on query level
as shown above.
Here is how to do it on DbContext
level.
public partial class MyDBEntities : DbContext
{
public MyDBEntities(): base("name=MyDBEntities")
{
this.Configuration.LazyLoadingEnabled = false;
}
}
Update : The 50 controllers where you don't need lazyloding you can disable it on constractor
level as shown below.Then you don't need to give it on query level
on each method.I think it's very quick way to implement it :)
public class YourAppService : IYourAppService
{
private readonly YourDbContext _context;
public YourAppService(YourDbContext context)
{
_context = context;
_context.Configuration.LazyLoadingEnabled = false;//to remove lazy loading
}
}
Is projecting lazy, eager or explicit in entity framework?
Lazy loading, eager loading and explicit loading works in the most common scenarios. Projection is replacement for eager loading because it can also load related entities with single query. Using projection make sense if you need to load entities with some complex query because eager loading doesn't work in these cases. Use projection if you need:
- Any kind of join or aggregation in the linq query. As I know
Include
is ignored once you start using manual joins. - Any kind of filtering or sorting in navigation property.
Include
can only load all related entities from navigation property without any sorting. Once you need to apply any where condition or order by on related entities you can't useInclude
and you must use projection.
Lazy Loading vs Eager Loading
I think it is good to categorize relations like this
When to use eager loading
- In "one side" of one-to-many relations that you sure are used every where with main entity. like User property of an Article. Category property of a Product.
- Generally When relations are not too much and eager loading will be good practice to reduce further queries on server.
When to use lazy loading
- Almost on every "collection side" of one-to-many relations. like Articles of User or Products of a Category
- You exactly know that you will not need a property instantly.
Note: like Transcendent said there may be disposal problem with lazy loading.
EF Core is lazy loading when I try to eager load with .Include()
Ok, after investigating the issue, there is a problem with EF Core 2.x lazy loading via proxies implementation. The related tracked issues are
- #15170: Eager loading include with using UseLazyLoadingProxies
- #12780: Store IsLoaded flags in proxy for better lazy-loading experience
The problem is that the navigation properties are eager loaded, but LazyLoader
does not know that when disposed - can't safely access context change tracker and simply is throwing exception. The relevant code can be seen here, in the very first line:
if (_disposed)
{
Logger.LazyLoadOnDisposedContextWarning(Context, entity, navigationName);
}
As I read it, it's supposed to be fixed in EF Core 3.0 when released with the following "breaking change" - Lazy-loading proxies no longer assume navigation properties are fully loaded. It also partially explains the current problem:
Old behavior
Before EF Core 3.0, once a
DbContext
was disposed there was no way of knowing if a given navigation property on an entity obtained from that context was fully loaded or not.
Unfortunately this doesn't help you with the current problem. The options I see are:
- Wait for EF Core 3.0 release
- Don't use lazy loading via proxies
Turn off the lazy loading on disposed context warning - by default it is
Throw
, change it toLog
orIgnore
, for instance:optionsBuilder.ConfigureWarnings(warnings => warnings
.Log(CoreEventId.LazyLoadOnDisposedContextWarning)
);
Coming from SQL to EF6 Which loading method should I start with? Lazy Loading, Explicit loading, Eager loading
My experience: I started with lazy loading as a beginner, then started to use Include when perf became unacceptable. Now I almost always write queries manually because I outgrew Include as well. The more performance matters to you the less convenience you can have. The more complex and demanding a code-base become the more you're forced to take control.
Often, lazy loading is fine one moment and the next moment you need to do manual querying and rip out all lazy loading stuff. The transition is often sudden and radical. Example: you render a list of questions on a page. Now, you also want to show question.Answers.Count() for each question. Lazy loading cannot do that. Now you need to introduce a custom view model and a custom query (questions.Select(q => new { q.ID, q.Title, AnswerCount = q.Answers.Count() })
). This always happens sooner or later, triggered by increasing business requirements. I usually go directly with the manual query.
To clarify, there is no well-performing way to solve the example I just gave, except with a custom query. If you didn't query when developing the first version of the project, you might have to tell the customer that this little change (just the added answer count) will cost a lot of money because you now have to rewrite some parts of the page. Inflexibility tends to be costly later.
Also, see the comments under the question for further context.
Lazy and Eager Loading in Entity Framework gives same result while using .Include() in both?
When you're explicitly using Include()
, you're preforming an Eager Loading. Obviously, disabling/enabling Lazy Loading has no effect.
The difference will be reflected when you'll omit the Include
and try to access the Products
navigation-property in some of your Category
instances. When Lazy-Loading is enabled, EF will load it from the database. When it's disabled, you'll get null
.
Related Topics
Windows 7 Progress Bar in Taskbar in C#
How to Compile and Run C# Program Without Using Visual Studio
Why Do We Need the "Event" Keyword While Defining Events
Suppress Null Value Types from Being Emitted by Xmlserializer
Ms Chart Rectangular Annotation Width in Percent and Not Pixel
Installing Windows Service Programmatically
How to Maximize the Browser Window in Selenium Webdriver (Selenium 2) Using C#
Httpclient Single Instance with Different Authentication Headers
Iis Express Immediately Shutting-Down Running Site After Stopping Web Application
How to Iterate Through a Datatable
How to Make Backgroundworker Return an Object
Binding to Custom Control Inside Datatemplate for Itemscontrol
C# Marking Class Property as Dirty
Getting Correct Image Rotation
Reference a .Net Core Library in a .Net 4.6 Project
Wait for Response from the Serial Port and Then Send Next Data