Working with Lazy Loading in Entity Framework Code First

Entity Framework 4 has Lazy Loading built-in and enabled by default.  Here’s a quick bit of code to show you how to work with this feature.  To get started with this, simply create a new Console Application and in nuget (Package Manager Console), run this command:

install-package EntityFramework.Sample

This will install a simple blog post example.  Copy and paste the following into your Program.cs file (replace everything):

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EFExample.Models;
 
namespace EFExample
{
    class Program
    {
        static void Main(string[] args)
        {
            var context = new BlogContext();
            Console.WriteLine("Default Lazy Loading setting is: " + context.Configuration.LazyLoadingEnabled);
            Console.WriteLine("Disabling Lazy Loading...");
            context.Configuration.LazyLoadingEnabled = false;
            
            // remove a post
            //context.Posts.Remove(context.Posts.First());
            //context.SaveChanges();
 
            // add a post
            //var newPost = new Post() { Title = "a test post", PublishDate = DateTime.Now, Comments = GetComments() };
            //context.Posts.Add(newPost);
            //context.SaveChanges();
 
            Console.WriteLine("Dependent Collection is Null with no Lazy Load, no Explicit Include");
            foreach (var post in context.Posts)
            {
                Console.WriteLine(post.Title);
                if (post.Comments != null)
                {
                    foreach (var comment in post.Comments)
                    {
                        Console.WriteLine("  -" + comment.Text);
                    }
                }
            }
            Console.WriteLine("".PadLeft(50, '-'));
 
            Console.WriteLine("With Explicit Include, It is Available (1 db call)");
            foreach (var post in context.Posts.Include("Comments"))
            {
                Console.WriteLine(post.Title);
                if (post.Comments != null)
                {
                    foreach (var comment in post.Comments)
                    {
                        Console.WriteLine("  -" + comment.Text);
                    }
                }
            }
            Console.WriteLine("".PadLeft(50, '-'));
            var anotherContext = new BlogContext();
            Console.WriteLine("With Lazy Loading On, It is Available But Populated Only On First Request");
            foreach (var post in anotherContext.Posts)
            {
                Console.WriteLine(post.Title);
                if (post.Comments != null)
                {
                    foreach (var comment in post.Comments)
                    {
                        Console.WriteLine("  -" + comment.Text);
                    }
                }
            }
 
 
            Console.ReadLine();
        }
 
        private static ICollection<Comment> GetComments()
        {
            var comments = new List<Comment>();
            for (int i = 0; i < 3; i++)
            {
                comments.Add(new Comment() { Author = "author" + i, Text = "comment " + i });
            }
            return comments;
        }
    }
}

I have three test cases shown here.  If you run the program (after adding a post using the commented add a post code) you should see this output:

SNAGHTML5bb800cc

By default, Entity Framework 4 uses Lazy Loading.  You can disable it with this code:

context.Configuration.LazyLoadingEnabled = false;

Once this is done, dependent collections like the Comments property of a Post in our example will be null if they are not specifically included.  If you know you need to include a dependent collection or property, you can do so with the .Include() method when you reference the DbSet, like so:

foreach (var post in context.Posts.Include("Comments"))

With Lazy Loading enabled (again, the default case), there is no need to specify the Include if you’re OK with the fact that in this example 2 calls will be made to the database:

Call One (List Posts – click to enlarge)

image

Call Two (List Comments for single post)

image

Now, let’s say you want to disable lazy loading by default (i.e. you don’t want to have to remember to set the property every time you instantiate a context).  This is quite simple if you’re using EF Code First and you have a DbContext like the BlogContext in this sample.  Simply add a constructor and in the constructor disable Lazy Loading, like so:

public class BlogContext : DbContext {
    public DbSet<Post> Posts { get; set; }
    public DbSet<Comment> Comments { get; set; }
 
    public BlogContext() : base()
    {
        this.Configuration.LazyLoadingEnabled = false;
    }
}

That’s it!  Now you know how to work with Lazy Loading in Entity Framework 4.

blog comments powered by Disqus