Lazy and Eager Loading in Entity Framework

Hi all, I hope everything is cool and fine, if you followed my previous article then you can find that I was talking about lazy loading. You can read it here:

Implement Lazy loading in C# using Lazy<T> Class

Fine. As we said, lazy loading is an architectural style and you can do it in many ways. In this article we will see how to implement lazy loading in the Entity Framework. I expect you to have the concepts of the Entity Framework and you understand the fundamental ideas behind lazy loading.

Yes, lazy loading is enabled in the Entity Framework ORM too, it is on by default in Entity Framework, so if you want to enable lazy loading in Entity Framework, you don't need to do anything. Haha.. And the opposite of lazy loading is eager loading that we will see in this example.

Oh, so let me show my DB structure because we know that the relationship in tables is essential to understand the concept.

A table relationship is very simple. I have one company table and one company_location table and they are connected by a foreign key. We see that there are two locations of the “Timken eng” company and the locations are Delhi and Kolkata.

Sql Query Analyzer

So, if we load the first record from the company table then for “Timekn Eng” there will be two more records that will be fetched from the company_location table.

Fine, now have a look at my ORM model.

ORM Module

Yes, it's showing a perfect relationship of two tables. Now, let's implement code to fetch data from the company table using the Entity Framework. Have a look at the following code.

Lazy loading by default in Entity Framework

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace ConsoleAPP

{

    class Program

    {

        static void Main(string[] args)

        {

            using (var ctx = new efDBEntities())

            {

                var company = ctx.companies.Take(1).ToList<company>();

                foreach (company c in company)

                {

                    Console.WriteLine("Company Name:" + c.company_name);

                    Console.WriteLine("Location:" + c.company_location.Count);

                }

            }

            Console.ReadLine();

        }

    }

}

We see that for “Timken eng” there are 2 in the location count. As we discussed, lazy loading is enabled by default. Let's now explain the output. Here the total 2 query is fireed in the DB. The first query is at the time of company loading and the next one is at the time of count loading within the foreach loop and the output is here.

Running Console Application

Now, we will disable lazy loading in the application and we will check the behavior of the application. Here is the code for turning off lazy loading that was enabled by default:

Eager loading

static void Main(string[] args)

{

    using (var ctx = new efDBEntities())

    {

        ctx.Configuration.LazyLoadingEnabled = false;

        var company = ctx.companies.Take(1).ToList<company>();

        foreach (company c in company)

        {

            Console.WriteLine("Company Name:" + c.company_name);

            Console.WriteLine("Location:" + c.company_location.Count);

        }

    }

    Console.ReadLine();

}

And we see that the number of counts for “Timken Eng” is 0 in this case. Because only one query was fired and the query within the foreach was not executed, so the count value is 0.

Eager Loading

So, to solve the problem, we can explicitly specify the table names that need to be loaded even when lazy loading is false. Here is the modified code:

static void Main(string[] args)

{

    using (var ctx = new efDBEntities())

    {

        ctx.Configuration.LazyLoadingEnabled = false;

        var company = ctx.companies.Include("company_location").Take(1).ToList<company>();

        foreach (company c in company)

        {

            Console.WriteLine("Company Name:" + c.company_name);

            Console.WriteLine("Location:" + c.company_location.Count);

        }

    }

    Console.ReadLine();

}

We have now specified a table name “company_location” in the query within Include(), it implies that the table is also loaded at the time of query execution. If we run the code above, we will see that the count property is populated again.

Finally

It's always necessary to turn off lazy loading at the time of serialization of the resultant object otherwise it will throw an error. Thanks for reading, in our next article we will learn Explicit loading.