实体框架4.1虚拟属性

Pan*_*yay 52 entity-framework-4.1

如果我在我的模型中声明实体关系为虚拟,则不需要Include在我的LINQ查询中使用该语句,对吧? -

例如:这是我的模型类:

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; }
}
Run Code Online (Sandbox Code Playgroud)

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

相反,我可以使用简单的var brandsAndProduct = pe.Brands.Where(brand => brand.BrandID == 22);,我将在访问时自动使相关实体可用.

我的理解是正确的吗?

另外,请告诉我在什么情况下我应该更喜欢一个?

Lad*_*nka 165

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

要使这项工作必须满足哪些规则:

  • 类中的所有导航属性必须是 virtual
  • 不得禁用动态代理创建(context.Configuration.ProxyCreationEnabled).它默认启用.
  • 不能禁用延迟加载(context.Configuration.LazyLoadingEnabled).它默认启用.
  • 必须附加实体(默认情况下,如果从数据库加载实体)到上下文并且不得处理上下文=延迟加载仅在用于从数据库加载它的生活上下文范围内(或者附加了代理实体)

延迟加载的反义词叫做eager loading,就是Include这样.如果使用Include导航属性与主实体一起加载.

延迟加载和急切加载的使用取决于您的需求和性能.Include在单个数据库查询中加载所有数据,但是当使用大量包含或加载大量实体​​时,它可能导致巨大的数据集.如果您确定需要Brand和所有Products进行处理,则应使用预先加载.

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

在更复杂的场景中,您可以发现这些策略都不能按您的需要运行,您可以使用第三种策略(称为显式加载)或单独查询来加载品牌,而不是使用所需品牌的产品.

显式加载具有与延迟加载类似的缺点,但您必须手动触发它:

context.Entry(brand).Collection(b => b.Products).Load();
Run Code Online (Sandbox Code Playgroud)

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

  • 我觉得这个答案简洁而完整......谢谢.提到"加载相关数据"http://msdn.microsoft.com/en-us/magazine/hh205756.aspx (3认同)