虚拟关键字在Entity Framework 4.1 POCO代码中有什么作用?

在EF Code First中的属性上使用virtual关键字是否有效? 有人可以在不同的情况下描述它的所有后果吗?

例如,我知道它可以控制延迟加载 – 如果在ICollection / one-to-many关系属性上使用virtual关键字,则默认情况下它将被延迟加载,而如果将virtual关键字取消,它将会急于加载。

在EF中使用POCO实体, virtual关键字还有什么其他效果? 我应该默认使用virtual的所有属性,或默认不使用它?

到目前为止,我知道这些影响。

  • 延迟加载 :任何virtual ICollections都将被延迟加载,除非您特别标记它们。
  • 更有效的变更跟踪 。 如果您满足以下所有要求,那么您的更改跟踪可以通过挂钩您的虚拟属性来使用更高效的方法。 从链接:

    要获得更改跟踪代理,基本规则是您的类必须是公共的,非抽象的或非密封的。 您的课程还必须为所有持久性属性实施公共虚拟获取器/设置器。 最后,您必须仅将基于集合的关系导航属性声明为ICollection<T> 。 它们不能是具体实现或从ICollection<T>派生的另一个接口(与延迟加载代理不同)

描述这个的另一个有用的链接是MSDN 创buildPOCO代理的要求 。

这个虚拟关键字与从entity framework(延迟加载,急切加载和显式加载)加载数据的主题有关。

如果要使用延迟加载来加载数据,则应使用虚拟关键字。

延迟加载是一个实体或实体集合在第一次访问时自动从数据库加载的过程。

例如,当使用下面定义的Blog实体类时,将在第一次访问Posts导航属性时加载相关的Posts:

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

可以通过使Posts属性非虚拟来closuresPosts集合的延迟加载。

如果延迟加载closures,那么使用加载(使用Include方法)或显式加载相关实体(使用Load方法),仍然可以加载Posts集合。

急切地装载:

 using (var context = new BloggingContext()) { // Load all blogs and related posts var blogs1 = context.Blogs .Include(b => b.Posts) .ToList(); } 

显式加载:

 using (var context = new BloggingContext()) { var blog = context.Blogs.Find(1); // Load the posts related to a given blog context.Entry(blog).Collection(p => p.Posts).Load(); }