本文介绍了实体框架4.1虚拟属性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如果我已在模型中将实体关系声明为虚拟的,则无需在LINQ查询中使用Include语句,对吗??-

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; }
}

现在,对于上述模型类,我不需要使用var brandsAndProduct = pe.Brands.Include("Products").Single(brand => brand.BrandID == 22);.

Now, for the above model class, i dont need to use the var brandsAndProduct = pe.Brands.Include("Products").Single(brand => brand.BrandID == 22); .

相反,我只能使用简单的var brandsAndProduct = pe.Brands.Where(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.

我的理解正确吗?

另外,请告诉我在什么情况下我应该优先选择另一种?

Also, please tell me in what situations i should prefer one over the other ??

推荐答案

您是正确的,但是要使该规则按预期工作则要复杂得多.如果定义导航属性virtual,EF将在运行时创建一个从Brand类派生的新类(动态代理),并改而使用它.这个新动态创建的类包含用于在首次访问时加载导航属性的逻辑.此功能称为延迟加载(或更好的透明延迟加载).

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).默认情况下启用.
  • 不得禁用延迟加载(context.Configuration.LazyLoadingEnabled).默认情况下启用.
  • 必须将实体附加到上下文(如果从数据库中加载实体,则为默认值),并且不得处置上下文=延迟加载仅在用于从数据库(或附加代理实体的位置)加载的活动上下文的范围内起作用./li>
  • All navigation properties in class must be virtual
  • Dynamic proxy creation must not be disabled (context.Configuration.ProxyCreationEnabled). It is enabled by default.
  • Lazy loading must not be disabled (context.Configuration.LazyLoadingEnabled). It is enabled by default.
  • Entity must be attached (default if you load entity from the database) to context and context must not be disposed = lazy loading works only within scope of living context used to load it from database (or where proxied entity was attached)

延迟加载的相反方法称为渴望加载",这就是Include的作用.如果使用Include,则导航属性会与主实体一起加载.

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.

延迟加载和急切加载的使用取决于您的需求以及性能. Include在单个数据库查询中加载所有数据,但可能导致.如果您确定需要Brand和所有Products进行处理,则应使用紧急加载.

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.

如果不确定所需的导航属性,则依次使用延迟加载.例如,如果您加载了100个品牌,但是您只需要访问一个品牌的产品,那么在初始查询中就不需要加载所有品牌的产品.延迟加载的缺点是每个导航属性的查询(数据库往返)=>如果您加载100个品牌而不包含include,并且您将在每个Brand实例中访问Products属性,则代码将生成另外100个查询以填充这些导航属性=急切加载将仅使用单一查询,而延迟加载将使用101个查询(这称为N + 1问题).

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();

显式加载的主要优点是过滤关系的能力.您可以在Load()之前使用Query(),并且可以使用任何过滤方法,甚至可以急于加载嵌套关系.

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.

这篇关于实体框架4.1虚拟属性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-15 14:48