Why exactly do we need to use the "virtual" keyword when declaring a navigation property? I understand that the Code First framework uses it somehow to recognize that the property is a navigation property, but I'd like to know how. Specifically, I'd like to know how it relates to the description given in the MSDN documentation for the "virtual" keyword: http://msdn.microsoft.com/en-us/library/9fkccyh4(v=vs.80).aspx
-
I think you should read here: http://stackoverflow.com/questions/5597760/what-effects-can-the-virtual-keyword-have-in-entity-framework-4-1-poco-code-fi – Denis Agarev Jan 14 '13 at 15:15
-
btw, the link you posted is broken. – Anonymous Jan 14 '13 at 15:17
-
1Thanks, I missed the "x" at the end of "aspx". http://msdn.microsoft.com/en-us/library/9fkccyh4(v=vs.80).aspx – nckbrzg Jan 14 '13 at 15:27
2 Answers
On runtime, Entity Framework will generate for you what's called proxy-entities. Those entities are objects of dynamically created types that derive from your entity types.
This allows you to use your entities as a POCO, which is a simple object that is not related to Entity Framework in any way, as it doesn't inherit from EntityObject
.
On runtime, the dynamically created entity type inherits from your POCO, and overrides all your virtual properties to add the Entity Framework stuff that allows lazy-loading in the properties getters.
Lazy loading is a complex process that requires your code to know about how the data comes from the database. As you don't want your domain classes to know about the database and the EF stuff, you abstract your entities from EF and add virtual properties, so EF can override your base POCO and add its DB-related stuff on runtime.
Same for change tracking.

- 48,145
- 10
- 116
- 176
Adding virtual
allows EF to generate a derived class that overrides the property and returns a set from the database.

- 868,454
- 176
- 1,908
- 1,964
-
4I would argue that explaining that this is for lazy-loading and/or change tracking would be better! – Matías Fidemraizer Jan 14 '13 at 15:14
-
Ah, so C# is just like Java in the way that it handles properties that are overridden by child classes? That is, say I declare have the following classes: public class A { public string Foo = {get; set;} } and public class B : A { public string Foo = {get; set;} } if I do the following operation B bar = new B{"hello"}; string test = ((A)bar).Foo test will be null? – nckbrzg Jan 14 '13 at 15:23
-
1@NicholasBranzburg: C# Requires properties to be specified as `virtual` in order to be overridden. Your example would not compile as it is invalid. You would need to do `public class A { public virtual string Foo { get; set; }` `public class B : A { public override string Foo { get; set; }`. Even in that scenario, your proposed operation of `((A)bar).Foo` would return `B.bar` due to the fact that it returns the most derived property. – Mike Bailey Jan 14 '13 at 16:05
-
@MikeBantegui Not true, I just tried it myself. It compiles fine. ((A)bar).Foo returns A.Foo, just like I thought. Try it yourself if you don't believe me. So it doesn't actually override it, it just pastes over it. The only way to access A.Foo from an object created as a B is to cast it to A, otherwise you will always get B.Foo. But your point is valid. If you actually try to override by using the override keyword, you will get a compiler error, this is why you need the "virtual" keyword. – nckbrzg Jan 14 '13 at 16:40