Eager , Lazy and explicit loading in EF6

20,861

Solution 1

If this small resume is true ?

Yes.

If it is true, what is the difference between eager and explicit loading?

Eager loading is the opposite of Lazy loading but Explicit loading is similar to lazy loading, except that: you explicitly retrieve the related data in code; it doesn't happen automatically when you access a navigation property. You load related data manually by getting the object state manager entry for an entity and calling the Collection.Load method for collections or the Reference.Load method for properties that hold a single entity.

From techblog:

Eager Loading :

Eager loading is the opposite of Lazy loading which is : The process of loading a specific set of related objects along with the objects that were explicitly requested in the query.

Explicit Loading :

Explicit loading is defined as : when objects are returned by a query, related objects are not loaded at the same time. By default, they are not loaded until explicitly requested using the Load method on a navigation property.

And:

If I Use lazy loading and I call for example dpc_gestion.dpc_participant, does the navigation properties loads?or I will get an exception?

You don't get any exception and the navigation properties should loads.

Is there a case when eager loading or explicit loading were better than lazy loading in performance and responsiveness?

Eager loading is typically more efficient when you need the related data for all retrieved rows of the primary table. And also when relations are not too much, eager loading will be good practice to reduce further queries on server. But when you know that you will not need a property instantly then lazy loading maybe a good choice. And also eager loading is a good choice in a situation where your db context would be disposed and lazy loading could not take place anymore. For example consider the following:

public List<Auction> GetAuctions()
{
    using (DataContext db = new DataContext())
    {
        return db.Auctions.ToList();
    }
}

After calling this method, You cannot load the related entity lazily because the db is disposed and so the Eager Loading would be a better choice here.

One more thing to note is: Lazy loading will produce several SQL request while Eager loading load data with one request. Eager loading is also a good choice to solve the n+1 selects issue in ORMs. Have a look at this post: What is the n+1 selects issue?

Solution 2

Question 1 and 2:

Your explanation of lazy loading and eager loading is correct.
The use of explicit loading is a bit different than you described.

EntityFramework returns IQueryable objects, which essentially contain the query to the database. But these are not executed until the first time they are enumerated.
Load executes the query so that its results are stored locally.
Calling Load is the same as calling ToList and throwing away that List, without having the overhead of creating the List.

Question 3:

If you use lazy loading, EntityFramework will take care of loading the navigation property for you, so you won't get an exception.
Keep in mind that this can take a while and make you application unresponsive.

Question 4:

In disconnected cases (e.g. network application) you can't use lazy loading, because these objects are translated into DTOs and then not tracked by EntityFramework.

Also, if you know you're going to use a navigation property, its good practice to load it eagerly, so you don't have to wait until they are loaded from the database.
For example, lets say you store the result in a list and bind it to a WPF DataGrid. If the DataGrid accesses a property that is not loaded yet, the user experiences a noticeable timeout until that property is displayed. Additionally the application will not respond during the loading time (if you dont load asynchronously).

Share:
20,861
Lamloumi Afif
Author by

Lamloumi Afif

Hi, I am a Software Development Engineer with a genuine interest in .Net framework. I enjoy reading books and practising sport. LinkedIn Viadeo

Updated on August 15, 2022

Comments

  • Lamloumi Afif
    Lamloumi Afif over 1 year

    I have read this tutorial and this article but I don't understand exactly the use of each loading type.

    I Explain

    I have this POCO :

    public partial class dpc_gestion
    {
        public dpc_gestion()
        {
            this.ass_reunion_participant = new HashSet<ass_reunion_participant>();
            this.dpc_participant = new HashSet<dpc_participant>();
            this.dpc_reunion = new HashSet<dpc_reunion>();
        }
    
        public int dpc_id_pk { get; set; }
        public Nullable<int> dpc_id_gdp_fk { get; set; }
        public Nullable<int> dpc_id_theme { get; set; }
        public int dpc_id_animateur_fk { get; set; }
        public Nullable<System.DateTime> dpc_date_creation { get; set; }
        public Nullable<System.DateTime> dpc_date_fin { get; set; }
        public Nullable<System.DateTime> dpc_date_engag_anim { get; set; }
        public Nullable<bool> dpc_flg_let_engag_anim { get; set; }
        public Nullable<bool> dpc_flg_fsoins_anim { get; set; }
        public virtual ICollection<ass_reunion_participant> ass_reunion_participant { get; set; }
        public virtual theme_dpc theme_dpc { get; set; }
        public virtual gdp_groupe_de_pair gdp_groupe_de_pair { get; set; }
        public virtual ICollection<dpc_participant> dpc_participant { get; set; }
        public virtual ICollection<dpc_reunion> dpc_reunion { get; set; }
    }
    

    I understood this :

    1. For Lazy loading : because the load is lazy, if I call the dbset dpc_gestion all navigation properties won't be loaded. This type of loading is the best in performance and responsiveness. It is enabled by default and If I'd like to re-enable it I have to set :

      context.Configuration.ProxyCreationEnabled = true;    
      context.Configuration.LazyLoadingEnabled = true;
      
    2. For the eager loading It is not lazy: it loaded all navigation properties when I load dpc_gestion. The navigation properties can be loaded using include method. To enable this loading type :

      context.Configuration.LazyLoadingEnabled = false;
      
    3. For the explicit loading It is like the eager loading but we use Load method instead of include.

    So I'd like to know :

    1. If this small resume is true ?
    2. If it is true, what is the difference between eager and explicit loading?
    3. If I Use lazy loading and I call for example dpc_gestion.dpc_participant, does the navigation properties loads?or I will get an exception?
    4. Is there a case when eager loading or explicit loading were better than lazy loading in performance and responsiveness?

    Thanks

  • Salah Akbari
    Salah Akbari over 8 years
    @LamloumiAfif...One more thing to note is: Lazy loading will produce several SQL request while Eager loading load data with one request.
  • Gert Arnold
    Gert Arnold over 8 years
    Also keep in mind that for lazy loading the context must be alive, otherwise an exception will be thrown. And I would say that in disconnected scenarios you can use lazy loading as long as you're building the object graph that's going to be serialized, although it's more common to load everything you need explicitly, either by Include or Load.
  • Jonathan Stark
    Jonathan Stark about 6 years
    Also, setting LazyLoadingEnabled = false does not enable eager loading. It disables lazy loading. It is possible to eager load using Include when lazy loading is enabled
  • Andes Lam
    Andes Lam almost 3 years
    @Colin Is it true that the only way of eager loading is using Include?
  • Jonathan Stark
    Jonathan Stark almost 3 years
    @AndesLam I would define eager loading as fetching entities up front in the original query - which I think would require Include. You can call Load on navigation properties - but I wouldn't call that eager loading docs.microsoft.com/en-us/ef/ef6/fundamentals/…
  • Andes Lam
    Andes Lam almost 3 years
    @Colin The reason I am confused is because in OP's words, "It is not lazy: it loaded all navigation properties when I load dpc_gestion". It is as if navigation properties are fetched in the first place in eager loading automatically. However, what I have learnt so far doesn't give me that impression--include is the only way and it is a manual process.