If i have declared entity relationship in my model as virtual then there is no need to use the Include
statement in my LINQ query, right ??-
For ex: This is my model class :
public class Brand { public int BrandID { get; set; } public string BrandName { get; set; } public string BrandDesc { get; set; } public string BrandUrl { get; set; } public virtual ICollection<Product> Products { get; set; } }
Now, for the above model class, i dont need to use the var brandsAndProduct = pe.Brands.Include("Products").Single(brand => brand.BrandID == 22);
.
Instead, I can just use the simple var brandsAndProduct = pe.Brands.Where(brand => brand.BrandID == 22);
and i will automatically have the related entity available when accessed.
Am I correct in my understanding ?
Also, please tell me in what situations i should prefer one over the other ??
In the context of EF, marking a property as virtual allows EF to use lazy loading to load it. For lazy loading to work EF has to create a proxy object that overrides your virtual properties with an implementation that loads the referenced entity when it is first accessed.
If you define your navigation property virtual , Entity Framework will at runtime create a new class (dynamic proxy) derived from your class and uses it instead of your original class. This new dynamically created class contains logic to load the navigation property when accessed for the first time.
Lazy loading is the process whereby an entity or collection of entities is automatically loaded from the database the first time that a property referring to the entity/entities is accessed. Lazy loading means delaying the loading of related data, until you specifically request for it.
You are correct but the rule is more complex to make it really work as expected. If you define your navigation property virtual
EF will at runtime create a new class (dynamic proxy) derived from your Brand
class and use it instead. This new dynamically created class contains logic to load navigation property when accessed for the first time. This feature is called lazy loading (or better transparent lazy loading).
What rules must be meet to make this work:
virtual
context.Configuration.ProxyCreationEnabled
). It is enabled by default.context.Configuration.LazyLoadingEnabled
). It is enabled by default.The opposite of lazy loading is called eager loading and that is what Include
does. If you use Include
your navigation property is loaded together with main entity.
Usage of lazy loading and eager loading depends on your needs and also on performance. Include
loads all data in single database query but it can result in huge data set when using a lot of includes or loading a lot of entities. If you are sure that you will need Brand
and all Products
for processing you should use eager loading.
Lazy loading is in turn used if you are not sure which navigation property you will need. For example if you load 100 brands but you will need to access only products from one brand it is not needed to load products for all brands in initial query. The disadvantage of the lazy loading is separate query (database roundtrip) for each navigation property => if you load 100 brands without include and you will access Products
property in each Brand
instance your code will generate another 100 queries to populate these navigation properties = eager loading would use just singe query but lazy loading used 101 queries (it is called N + 1 problem).
In more complex scenarios you can find that neither of these strategies perform as you need and you can use either third strategy called explicit loading or separate queries to load brands and than products for all brands you need.
Explicit loading has similar disadvantages as lazy loading but you must trigger it manually:
context.Entry(brand).Collection(b => b.Products).Load();
The main advantages for explicit loading is ability to filter relation. You can use Query()
before Load()
and use any filtering or even eager loading of nested relations.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With