Working with Lazy Loading in Entity Framework Code First

Posted by: Steven Smith, on 03 Oct 2011 | View original | Bookmarked: 0 time(s)

Entity Framework 4 has Lazy Loading built-in and enabled by default.  Heres 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 youre 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, lets say you want to disable lazy loading by default (i.e. you dont want to have to remember to set the property every time you instantiate a context).  This is quite simple if youre 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;
    }
}

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


Advertisement
Free Agile Project Management Tool from Telerik
TeamPulse Community Edition helps your team effectively capture requirements, manage project plans, assign and track work, and most importantly, be continually connected with each other.
Category: Visual Studio | Other Posts: View all posts by this blogger | Report as irrelevant | View bloggers stats | Views: 427 | Hits: 12

News Categories

.NET | Agile | Ajax | Architecture | ASP.NET | BizTalk | C# | Certification | Data | DataGrid | DataSet | Debugger | DotNetNuke | Events | GridView | IIS | Indigo | JavaScript | Mobile | Mono | Patterns and Practices | Performance | Podcast | Refactor | Regex | Security | Sharepoint | Silverlight | Smart Client Applications | Software | SQL | VB.NET | Visual Studio | W3 | WCF | WinFx | WPF | WSE | XAML | XLinq | XML | XSD