Reputation:
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!
Upvotes: 2
Views: 798
Reputation: 6501
You can use Include also with lazy load enabled. Not using Include makes the code more clear so usually I use Include only where I have performance issues.
Also, navigation can change during the project life so with lazy load you don't need to remember about it.
And also, you can't use lazy load during serialization otherwise you will probably serialize all the database.
Just for information, Include also often generates very ugly queries (but I never had performance issues).
About parent properties is only usefull for navigation purpose (i.e. you can navigate from a Letter to a Folder then to the Letters of the Folder).
Upvotes: 0
Reputation: 62159
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
BOth are not smart. That is equivalent to taking the battery out of your car just to shut down the engine.
Lazy loading ENABLED does not meant it is USED, same with the virtual
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?
THat the later would be ABLE to use lazy loading (which you can not after your sabotage).
Include can not be used when Lazy loading is enabled?
Says who? It can totally - in this case lazy loading will simply not happening for already included elements, which gives you freedom to choose lazy loading or not on a case by case basis.
Upvotes: 0
Reputation: 14498
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.
Upvotes: 2