在实体框架4.1 POCO Code First中,virtual关键字有什么影响?

在EF Code First的属性上使用virtual关键字时是否有影响?有人能描述一下它在不同情况下的所有后果吗?

例如,我知道它可以控制延迟加载——如果你在ICollection/一对多关系属性上使用virtual关键字,默认情况下它将被惰性加载,而如果你不使用virtual关键字,它将被快速加载。

在EF中virtual关键字对POCO实体有什么其他影响?我是否应该默认使用virtual对我的所有属性,或默认不使用它?

101875 次浏览

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

  • 延迟加载:任何virtual集合都将被惰性加载,除非你特别标记了它们。
  • < p > 更有效的变更跟踪。如果您满足以下所有要求,那么您的变更跟踪可以使用更有效的方法,即绑定虚拟属性。从链接:

    要获取变更跟踪代理,请使用 基本规则是你的类必须是 公开的,非抽象的或非密封的。 你的类也必须实现public 所有的虚拟getter /setter 持久化的属性。 最后,必须声明集合 基于关系的导航 属性仅为ICollection<T>。 它们不可能是具体的 实现或其他接口 派生自ICollection<T> (a 不同于延迟加载 代理)< / p > 李< /引用> < / >

另一个描述这一点的有用链接是MSDN的创建POCO代理的要求

这个virtual关键字与从实体框架加载数据的主题有关(惰性加载、即时加载和显式加载)。

当你想用惰性加载加载数据时,你应该使用< em >虚拟< / em >关键字。

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

例如,当使用下面定义的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属性设置为非虚拟属性来关闭Posts集合的延迟加载。

如果延迟加载关闭,Posts集合的加载仍然可以使用立即加载(使用Include方法)或显式加载相关实体(使用Load方法)来实现。

急切地加载:

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