为什么导航属性在EF中默认为虚拟

时间:2014-09-07 22:52:14

标签: entity-framework navigation-properties

我在EF 6.x中使用了以下POCO类。

我的问题:为什么'帖子'的导航属性?在' Blog'声明为虚拟的实体?

public class Blog 
{  
    public int BlogId { get; set; }  
    public string Name { get; set; }  
    public string Url { get; set; }  
    public string Tags { get; set; }  

    public virtual ICollection<Post> Posts { get; set; }  
}

1 个答案:

答案 0 :(得分:76)

如果定义导航属性virtual,Entity Framework将在运行时创建一个从您的类派生的新类(动态代理),并使用它而不是原始类。这个新动态创建的类包含第一次访问时加载导航属性的逻辑。这被称为&#34;延迟加载&#34;。它使Entity Framework能够避免加载数据库中不需要的整个依赖对象树。

在某些情况下,最好使用&#34; Eager Loading&#34;相反,特别是如果您知道在某些时候您将与相关对象进行交互。

Julie Lerman确实是所有实体框架的权威,她在MSDN文章Demystifying Entity Framework Strategies: Loading Related Data中很好地解释了这个过程

  

使用Include进行预先加载对于您事先知道要查询所有核心数据的相关数据的情况非常有用。但要记住两个潜在的缺点。如果您有太多包含或导航路径,实体框架可能会生成性能不佳的查询。由于使用Include编写的简便性,您应该注意返回比必要更多的相关数据。

     

延迟加载可以非常方便地在幕后为您检索相关数据,以响应仅提及相关数据的代码。它也使编码更简单,但你应该认真对待它与数据库的相互作用。当只需要一两个时,您可能会导致40次访问数据库。

如果您正在开发一个Web应用程序,其中与服务器的每次通信都是一个新的上下文,Lazy Loading只会产生不必要的开销来维护永远不会加载的相关对象的动态类。很多人会在这些场景中禁用延迟加载。最终,它仍然最好评估EF构建的SQL查询,并确定哪些选项最适合您正在开发的场景。