Entity Framework 4.1 Virtual Properties

If I declared the connection with the entity in my model as virtual, then there is no need to use the Include statement in my LINQ query, right? -

For example: 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 model class specified above, I do not need to use var brandsAndProduct = pe.Brands.Include("Products").Single(brand => brand.BrandID == 22); .

Instead, I can simply use a simple var brandsAndProduct = pe.Brands.Where(brand => brand.BrandID == 22); , and I will automatically have a linked object available on access.

Am I right in my understanding?

In addition, please tell me in which situations should I prefer one after another?

+49
Oct 12 2018-11-12T00:
source share
1 answer

You are right, but the rule is more complicated so that it really works as expected. If you define your navigation property virtual , EF at runtime will create a new class (dynamic proxy) derived from your Brand class, and use it instead. This new dynamically created class contains logic for loading the navigation property on first access. This function is called lazy loading (or more transparent lazy loading).

What rules must be followed to complete this work:

  • All navigation properties in the class must be virtual
  • Cannot disable dynamic proxy creation ( context.Configuration.ProxyCreationEnabled ). It is enabled by default.
  • Lazy loading should not be disabled ( context.Configuration.LazyLoadingEnabled ). It is enabled by default.
  • The object must be attached (by default, if you load the object from the database) into the context and the context should not be deleted = lazy loading works only within the context of the life used to load it from the database (or where the proxy object was attached)

The opposite of lazy loading is called impatient loading, and this is what Include does. If you use Include , your navigation property is loaded with the main object.

Using lazy loading and fast loading depends on your needs as well as performance. Include loads all the data in one database query, but can lead to a huge data set when using a large number of inclusions or loading multiple objects. If you are sure that you will need Brand and all Products for processing, you should use active download.

In turn, lazy loading is used if you are not sure which navigation property you will need. For example, if you download 100 brands, but you only need to access products from one brand, there is no need to download products for all brands in the original request. The disadvantage of lazy loading is a separate request (database callback) for each navigation property => if you download 100 brands without inclusion and you get access to the Products property in each Brand instance, your code will generate another 100 requests to fill these properties navigation = loaded download will use only one request, but lazy loading used 101 requests (this is called N + 1 problem).

In more complex scenarios, you may find that none of these strategies work as needed, and you can use either a third strategy called explicit loading, or separate requests to download brands and products for all brands that you need.

Explicit loading has the same disadvantages as lazy loading, but you must start it manually:

 context.Entry(brand).Collection(b => b.Products).Load(); 

The main advantages for explicit loading are the ability to filter the relation. You can use Query() to Load() and use any filtering or even eager loading of nested relationships.

+158
Oct 12 '11 at
source share
— -



All Articles