In most circumstances I don’t think lazy loading is a good idea. If you were using Entity Framework, you may be using Lazy Loading unintentionally since it’s built in by default.
To eager load a related entity, you specify the related entity to be populated with the
Include() method. This is applicable in EF and EF Core. However in Entity Framework 6.x, if you do not
Include() a related entity, and access that navigation property, but default it will be lazy loaded.
Meaning a SQL statement will occur to load the related entity. If you are iterating over a collection, this is where the N+1 comes from.
I assume this is why Entity Framework Core held out until 2.1 before providing a way to lazy load related entities since it’s now an opt-in.
As mentioned, Entity Framework Core 2.1 now supports Lazy Loading as an opt-in.
I don’t recommend turning this on from a fresh project, but it may be applicable if you are migrating from Entity Framework 6.x to EF Core. You can get pretty far with your existing LINQ queries without having to rewrite a large portion of your app.
Enable Lazy Loading
I don’t want to re-write the docs on how to enable Lazy Loading, so check them out. However, I do want to show my preferred method and strategy that if you enable lazy loading, that you can log when it occurs.
This will provide you insights about where in your existing LINQ you are not calling
Include() and eager loading the related entity.
First, to enable lazy loading, I’m going to add a param of
Action<object, string> that will be injected into your entity by Entity Framework. If the related entity being accessed is null, I’m going to Load the related entity, but also log out to the Console. Obviously you would be using the logging tool you prefer, for this demo I’m just creating a console application.
Here’s a simple console application that first inserts a parent entity with two children. Then on the first call it does not Include() and will force lazy loading, which in turn will be logged to the console. In the second call, Include() will be called and no lazy loading occurs.
Have you migrated from Entity Framework 6.x to Entity Framework Core? I’d love to hear about it in the comments or on Twitter.