0

How to replace Eager Loading by using Lazy loading ?

Lets say like this.I am having below kind of EF query with lot of Include keys .Performance wise This is very slow.

So how can I improve the performance of below code by using Lazy loading ?

from owner in Catalog.Owners
            where owner.Key == ownerKey
            from invoice in owner.Invoices
            where invoice.Provider.Key == providerKey
            where invoice.Id == id
            select invoice)
            .Include(i => i.Owner.Credits)
            .Include(i => i.Provider)
            .Include(i => i.Items.Select(s => s.Allocation.Service))
            .Include(i => i.Items.Select(s => s.Allocation.Pet))
            .FirstOrDefault();

If you can give me a sample code explanation it's perfect.

2 Answers 2

2

With EF 4.1 and greater, you just need to make sure to define your code-first navigation properties (properties that link to other entities) as virtual. Then, if you are inside a DbContext, the linked entity will only be queried from the database when it is actually used (lazy loaded).

However, eager loading is used when you want all the data right away. There are usually good reasons for this. So, I would first say that if you don't know why you are eager loading, then don't do it. Make sure your properties that link entities are virtual and then get rid of the .Include statements in your query.

However, if you are taking the data you are querying outside of a DbContext or you use the data right away it makes sense to pull that data into memory for the duration of your operation.

So, in response to your question, it is not always a case of just replacing eager loading with lazy loading. You must look at what is being done with the data once it is queried and see how to only return the minimum set you need.

Added example:

    public class Person
    {
        public int Id { get; set; }
        public string Name { get; set; }

        public virtual ICollection<Car> Cars { get; set; } //make it virtual

    }

    public class Car
    {
        public int Id { get; set; }
        public string Make { get; set; }
        public string Model { get; set; }
    }

    public class MyContext : DbContext
    {
        public IDbSet<Person> People { get; set; }
        public IDbSet<Car> Cars { get; set; }
    }

    class Program
    {
        private static void Main(string[] args)
        {
            using (var context = new MyContext())
            {
                var person = context.People.FirstOrDefault(p => p.Id == 1); // calls the database

                var car = person.Cars.FirstOrDefault(c => c.Id == 2); // Lazy loads Cars

            }
        }
    }
Sign up to request clarification or add additional context in comments.

3 Comments

Could you give simple example for how to do lazy loading ?
@Sampath I've added an example. As you can see, the Cars navigation property is virtual. This allows EF to lazy load it when needed.
But take care Lazy Loading may cause N+1 issue
2

If you don't use eager loading (Include calls) lazy loading will be used automatically if you have everything correctly set-up:

  • virtual navigation properties
  • lazy loading and proxy creation allowed (should be by default)
  • lazy loading performed in scope of object context used to load the root object

Lazy loading executes query to load related entities only when you access the navigation property so it can improve performance for example if you don't need all of related data all the time but if you need them always it can lead to even worse performance due to lot of database roundtrips.

2 Comments

Could you give simple example for how to do lazy loading ?
var owner = invoice.Owner; - if you don't have owner loaded and lazy loading is working EF will load it when this code is called.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.