Search code examples
c#entity-frameworkentity-framework-6lazy-loadingeager-loading

Entity framework Eager and Lazy load


Trying to figure out the difference between Lazy and Eager loading in entity frameowrk. Say I have the following models:

public interface IBaseEntityObject 
{
    public int Id {get; set;}
}


public abstract class BaseEntityObject : IBaseEntityObject
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int Id {get; set;}
}


public class Folder : BaseEntityObject
{   
    [DataMember]
    public string Name {get; set;}

    [DataMember]
    public virtual List<Letter> Letters {get; set;} 
}


public abstract class Letter : BaseEntityObject
{   
    [DataMember]
    public string Title {get; set;}

    [DataMember]
    public string Content {get; set;}

    public virtual Folder Folder {get; set;}

    [DataMember]
    public int FolderId {get; set;}

    [DataMember]
    public DateTime CreationDate {get; set;}
}

public class OutgoingLetter : Letter
{
    // .. OutgoingLetter properties
}

public class ReceviedLetter : Letter
{
    // .. ReceviedLetter properties
}


public class MyDbContext : DbContext
{
    public DbSet<Folder> Folders {get; set;}

    public DbSet<Letter> Letters {get; set;}


    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);

        // Folder <-> Letters       
        modelBuilder.Entity<Letter>()
        .HasRequired(t => t.Folder)
        .WithMany(f => f.Letters)
        .HasForeignKey(t => t.FolderId)
        .WillCascadeOnDelete(true);
    }
}

Whenever I ask a folder from the data base, it's main purpose is for accessing the Letters in it.. Therefore, will it be best if I already load it from the beginning instead of making another database call when accessing the Letters property am I correct?

I've read that disabling the Lazy load is done by configuring it in the ctor with by setting the EnableLazyLoading property to false and removing virtual key word from the letters list.

What would be the difference if I just use Include(x => x.Lettters) whenever I ask for a folder and keep the Lazy loading enabled? Include can not be used when Lazy loading is enabled?

Moreover is there any relation between the Folder property that is held in Letter model to the lazy loading? I don't use the Folder when asking for a letter, yet most models around I've seen contain the Father property in one to many relationship and I don't really understand why.

Thanks!


Solution

  • Whenever I ask a folder from the data base, it's main purpose is for accessing the Letters in it.. Therefore, will it be best if I already load it from the beginning instead of making another database call when accessing the Letters property am I correct?

    Yup, correct.

    I've read that disabling the Lazy load is done by configuring it in the ctor with by setting the EnableLazyLoading property to false and removing virtual key word from the letters list.

    If you never want lazy loading for a certain property, remove the virtual keyword. If you sometimes need it and sometimes you don't, disable lazyloading when you create a new context in your code.

    What would be the difference if I just use Include(x => x.Lettters) whenever I ask for a folder and keep the Lazy loading enabled? Include can not be used when Lazy loading is enabled?

    They have no effect on eachother. If you don't include the letters, and you try to access the property, EF will make another call to db to fetch them (lazy loading), if you include them, they're available and no extra call to database is made.

    Moreover is there any relation between the Folder property that is held in Letter model to the lazy loading? I don't use the Folder when asking for a letter, yet most models around I've seen contain the Father property in one to many relationship and I don't really understand why.

    In most examples, the navigation property is defined in both ways, but if you never need to get the folder from a letter, it makes perfect sense not to define that property in your letter model.