EF Core lazy loading of navigation properties’ null value problem and solution
Problem Description
Consider the following model:
<code class="language-csharp">public class Mutant { public long Id { get; set; } public long OriginalCodeId { get; set; } public virtual OriginalCode OriginalCode { get; set; } } public class OriginalCode { public long Id { get; set; } public virtual List<Mutant> Mutants { get; set; } }</code>
Define the relationship in the OnModelCreating
method of DbContext:
<code class="language-csharp">modelBuilder.Entity<Mutant>() .HasOne(m => m.OriginalCode) .WithMany(oc => oc.Mutants) .HasForeignKey(m => m.OriginalCodeId) .OnDelete(DeleteBehavior.Restrict);</code>
When querying a Mutant, the OriginalCode
property is initially empty. However, if you query OriginalCode
before querying the Mutant, the OriginalCode
attribute will be populated.
Cause Analysis
This behavior is documented in the "Loading related data" section of the EF Core documentation:
Entity Framework Core does not currently support lazy loading, so typically navigation properties will be empty until you load them via preloading or explicitly.
However, the "Preloading" section contains the following:
Tips Entity Framework Core will automatically fix the navigation properties of any other entities that were previously loaded into the context instance. Therefore, even if you do not explicitly include data for a navigation property, the property may still be populated if some or all of the related entities were previously loaded.
Solution
Solve the first problem (navigation attribute is empty):
Use available methods of loading relevant data, such as preloading:
<code class="language-csharp">var mutants = db.Mutants.Include(m => m.OriginalCode).ToList();</code>
Fix the second issue (preloading related entities causing navigation properties to be populated):
This behavior is "by design" and cannot be controlled. To avoid this problem:
AsNoTracking()
). EF Core v2.1 and later updates:
EF Core v2.1 supports lazy loading, but it is not enabled by default. To enable it:
virtual
. Microsoft.EntityFrameworkCore.Proxies
NuGet package. UseLazyLoadingProxies()
to enable lazy loading. With the above approach, you can effectively manage navigation property loading in EF Core, avoid null value issues and improve code predictability.
The above is the detailed content of Why are EF Core navigation properties null until explicitly loaded, and how can I consistently populate them?. For more information, please follow other related articles on the PHP Chinese website!