它允许实体框架围绕虚拟属性创建一个代理,这样属性就可以支持延迟加载和更有效的更改跟踪。请参阅虚拟关键字在实体框架4.1 POCO代码中有什么影响?进行更深入的讨论。
Edit to clarify "create a proxy around":
By "create a proxy around", I'm referring specifically to what the Entity Framework does. The Entity Framework requires your navigation properties to be marked as virtual so that lazy loading and efficient change tracking are supported. See Requirements for Creating POCO Proxies.
The Entity Framework uses inheritance to support this functionality, which is why it requires certain properties to be marked virtual in your base class POCOs. It literally creates new types that derive from your POCO types. So your POCO is acting as a base type for the Entity Framework's dynamically created subclasses. That's what I meant by "create a proxy around".
The dynamically created subclasses that the Entity Framework creates become apparent when using the Entity Framework at runtime, not at static compilation time. And only if you enable the Entity Framework's lazy loading or change tracking features. If you opt to never use the lazy loading or change tracking features of the Entity Framework (which is not the default), then you needn't declare any of your navigation properties as virtual. You are then responsible for loading those navigation properties yourself, either using what the Entity Framework refers to as "eager loading", or manually retrieving related types across multiple database queries. You can and should use lazy loading and change tracking features for your navigation properties in many scenarios though.
如果您要创建一个独立的类并将属性标记为虚的,并在您自己的应用程序中简单地构造和使用这些类的实例,完全超出实体框架的范围,那么您的虚属性本身不会为您带来任何好处。
编辑以描述将属性标记为虚拟的原因
属性如:
public ICollection<RSVP> RSVPs { get; set; }
不是场,不应该被认为是场。它们被称为getter和setter,在编译时,它们被转换为方法。
//Internally the code looks more like this:
public ICollection<RSVP> get_RSVPs()
{
return _RSVPs;
}
public void set_RSVPs(RSVP value)
{
_RSVPs = value;
}
private RSVP _RSVPs;
这就是为什么它们在实体框架中被标记为虚拟的原因;它允许动态创建的类覆盖内部生成的get和set函数。如果你的导航属性getter/setter在你的实体框架使用中为你工作,试着修改它们为属性,重新编译,看看实体框架是否仍然能够正常工作:
public virtual ICollection<RSVP> RSVPs;