Eager Loading
In contrast to lazy loading, eager loading loads all entities related with parent entity automatically. Lazy loading is not supported in legacy versions so first, let us discuss eager loading as an example so that we can understand how beneficial lazy loading is. The below example is created with Entity Framework Core 2.0.
- public class User
- {
-
- [Key]
- public int UserId { get; set; }
- public string UserName { get; set; }
-
- public virtual ICollection<Post> Post { get; set; }
-
- }
-
- public class Post
- {
-
- [Key]
- public int PostId { get; set; }
- public string Title { get; set; }
- public DateTime CreatedOn { get; set; }
- public string Content { get; set; }
- public virtual User User { get; set; }
-
- }
Here is a small code for Eager Loading.
- static void Main(string[] args)
- {
- var db = new TestDbContext();
- User usr = db.Users.Include(p => p.Post ).Where(u => u.UserId == 1).FirstOrDefault();
-
- foreach (var post in usr.Post)
- Console.WriteLine(post.Title);
-
- }
As soon as line 14 is executed, the SQL Server Profiler shows 2 queries on 2 entities executed.
You can see in the profiler that related entities are also loaded immediately. This immediate loading can be stopped, and called when needed, with lazy loading.
Lazy Loading
Lazy Loading is the default behavior of LINQ that’s why it is the default behavior of EF Core. With lazy loading, all related entities are not loaded along with the parent entity automatically. For example: If the User entity has a foreign key in the Post entity. With lazy loading, only the User’s data would be loaded, the Post entity would be loaded on demand.
Lazy loading is useful when the relationship between entities is a one-to-many relationship and you are sure that related entities are not used instantly. It can help in performance; for example, if you have huge data, then with the help of lazy loading, you can reduce application startup time, lessen the memory usage, and reduce the load on DBMS (fewer queries to the server in a time). Lazy loading is not supported by legacy EF Core versions, so we would discuss an example with Entity Framework Core 2.1 only.
Install Microsoft.EntityFrameworkCore.Proxies NuGet package and make changes to your Context class. Just add "UseLazyLoadingProxies".
- class TestDbContext : DbContext
- {
- public DbSet<Post> Posts { get; set; }
- public DbSet<User> Users { get; set; }
-
- protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
- {
- optionsBuilder.UseLazyLoadingProxies();
-
- optionsBuilder.UseSqlServer(@"Server=MUKESHTest;Database=Test2.1;Trusted_Connection=True;");
- }
- }
Remove Eager Loading by removing "include" and use Lazy Loading.
- static void Main(string[] args)
- {
- var db = new TestDbContext();
- var usr = db.Users.Where(u => u.UserId == 1).FirstOrDefault();
- Console.WriteLine("Now, loading related entities");
-
-
- foreach (var post in usr.Post)
- Console.WriteLine(post.Title);
- }
When we run the above code, the Profiler after line 14 looks like the following.
When we run to line 17, we see related entities loading.
Conclusion
We can see in the above example that it is easy to stop the loading of related entities. It is a really nice and a well-needed feature in Entity Framework Core 2.1.