【问题标题】:Entity Framework 4.1 Virtual PropertiesEntity Framework 4.1 虚拟属性
【发布时间】:2011-12-06 00:38:10
【问题描述】:

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

例如:这是我的模型类:

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 =&gt; brand.BrandID == 22);

相反,我可以只使用简单的var brandsAndProduct = pe.Brands.Where(brand =&gt; brand.BrandID == 22);,并且在访问时我会自动获得相关实体。

我的理解正确吗?

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

【问题讨论】:

    标签: entity-framework-4.1


    【解决方案1】:

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

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

    • 类中的所有导航属性都必须是virtual
    • 不得禁用动态代理创建 (context.Configuration.ProxyCreationEnabled)。默认启用。
    • 不得禁用延迟加载 (context.Configuration.LazyLoadingEnabled)。默认启用。
    • 实体必须附加(如果您从数据库加载实体则默认)到上下文并且不得释放上下文 = 延迟加载仅在用于从数据库加载它的活动上下文范围内工作(或附加代理实体的位置)

    延迟加载的反面称为急切加载,这就是Include 所做的。如果您使用Include,您的导航属性将与主实体一起加载。

    延迟加载和急切加载的使用取决于您的需求以及性能。 Include 在单个数据库查询中加载所有数据,但在使用大量包含或加载大量实体​​时可能会导致 huge data set。如果您确定需要Brand 和所有Products 进行处理,您应该使用预加载。

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

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

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

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

    显式加载的主要优点是能够过滤关系。您可以在Load() 之前使用Query(),并使用任何过滤甚至预先加载嵌套关系。

    【讨论】:

    • 我觉得这个答案简洁而完整......谢谢。引用“加载相关数据”msdn.microsoft.com/en-us/magazine/hh205756.aspx
    • 感谢您的回答。它在 2016 年仍然对我有帮助。我还有一个问题:有没有办法总是在一次调用中急切加载每个属性?由于在某些情况下,模型具有多个导航属性,并且每次都需要加载。
    猜你喜欢
    • 1970-01-01
    • 2011-08-15
    • 1970-01-01
    • 2012-05-10
    • 1970-01-01
    • 2011-11-21
    • 1970-01-01
    • 1970-01-01
    • 2011-09-06
    相关资源
    最近更新 更多