Coder Perfect

Why do Entity Framework model specifications use the term ‘virtual’ for class properties?

Problem

http://blogs.asp.net/scottgu/archive/2010/07/16/code-first-development-with-entity-framework-4.aspx

The following is an example of code from the blog:

public class Dinner
{
   public int DinnerID { get; set; }
   public string Title { get; set; }
   public DateTime EventDate { get; set; }
   public string Address { get; set; }
   public string HostedBy { get; set; }
   public virtual ICollection<RSVP> RSVPs { get; set; }
}

public class RSVP
{
   public int RsvpID { get; set; }
   public int DinnerID { get; set; }
   public string AttendeeEmail { get; set; }
   public virtual Dinner Dinner { get; set; }
}

When defining a property in a class, what is the purpose of utilizing virtual? What kind of impact does it have?

Asked by Gary Jones

Solution #1

It enables the Entity Framework to construct a proxy around the virtual property, allowing for lazy loading and more efficient change tracking. In Entity Framework 4.1 POCO Code First, see What effect(s) might the virtual keyword have? for a more in-depth examination

“Create a proxy around” has been clarified: I’m referring to what the Entity Framework does when I say “build a proxy around.” To allow lazy loading and efficient change tracking, the Entity Framework requires that your navigation properties be designated as virtual. Requirements for Creating POCO Proxies may be found here. To offer this feature, the Entity Framework leverages inheritance, which is why certain attributes in your base class POCOs must be designated virtual. It essentially generates new kinds based on your POCO types. As a result, the Entity Framework’s dynamically produced subclasses use your POCO as a base type. That’s what “build a proxy around” means.

Change tracking features or load zy. You don’t need to define any of your navigation properties as virtual if you never utilize the Entity Framework’s lazy loading or change tracking features (which is not the default). You must then load those navigation properties manually, either via “eager loading” as described by the Entity Framework, or manually obtaining related types across many database queries. In many instances, though, you can and should employ slow loading and change tracking features for your navigation properties.

If you create a standalone class and designate properties as virtual, then construct and use instances of that class in your own application, fully outside of the scope of the Entity Framework, your virtual properties would be useless.

Edit to explain why attributes are designated as virtual.

Properties such as:

 public ICollection<RSVP> RSVPs { get; set; }

Are not fields and should not be considered so. These are known as getters and setters, and they are turned to methods during compilation.

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

That’s why they’re tagged as virtual in the Entity Framework; it lets dynamically built classes override the get and set functions that are generated internally. Whether your Entity Framework navigation property getter/setters are functioning for you, consider converting them to just properties, recompiling, and seeing if the Entity Framework still works:

 public virtual ICollection<RSVP> RSVPs;

Answered by Shan Plourde

Solution #2

The virtual keyword in C# allows child classes to override a method or property. Please see the MSDN reference on the ‘virtual’ keyword for further information.

UPDATE: While this does not answer the issue as it is now posed, I’ll leave it here for anyone looking for a straightforward response to the original, non-descriptive query.

Answered by M.Babcock

Solution #3

I understand the OP’s dissatisfaction; nevertheless, this use of virtual is not for the templated abstraction for which the defacto virtual modifier is useful.

If anyone is still having trouble, I’d want to provide my perspective, since I try to keep the solutions simple and the language to a minimum:

Lazy loading, which is the equivalent of prepping things for future execution, is used by Entity Framework in a basic piece. That corresponds to the ‘virtual’ modifier, but there’s more to it.

Using a virtual navigation property in Entity Framework allows you to represent it as a nullable Foreign Key in SQL. When running a query, you don’t have to eagerly join every keyed table, but when you require the data, it becomes demand-driven.

Because many navigation attributes are initially irrelevant, I also mentioned nullable. You don’t have to wait until an order is processed to create a customer in a customer / Orders scenario. You can, but if you used a multi-stage process to get there, you might need to save the client data for later use or deployment to subsequent orders. You’d have to set up every Foreign Key and relational field on the save if all nav properties were implemented. This effectively puts the data back into memory, defeating the purpose of persistence.

So, while it may appear cryptic at runtime, I’ve found that the best rule of thumb to follow is: if you’re outputting data (reading into a View Model or Serializable Model) and need values before references, don’t use virtual; if you’re outputting data (reading into a View Model or Serializable Model) and need values before references, don’t use virtual; if you’re outputting data (reading into a View Model or Seriali The code will make good use of reference, comparable to using nullable value properties int? long?, if your scope is collecting data that may be incomplete or a need to search without requiring every search parameter to be completed for a search. Similarly to instantiating an object and beginning it at null, abstracting your business logic from your data collection until the need to inject it offers significant speed benefits. Entity Framework makes extensive use of reflection.

Using overloaded tech lingo like proxies, delegates, handlers, and the like never made sense to me. It can get complicated with these after you reach your third or fourth programming language.

Answered by Nathan Teague

Solution #4

“ASP.NET MVC 5 with Bootstrap and Knockout.js” from the book “ASP.NET MVC 5 with Bootstrap and Knockout.js”

Answered by Hassan Rahman

Solution #5

Marking a property as virtual in the context of EF allows EF to load it using lazy loading. EF must construct a proxy object that overrides your virtual properties with an implementation that loads the referenced entity when it is first accessed in order for lazy loading to operate. Lazy loading will not operate if the property is not marked as virtual.

Answered by Shakeer Hussain

Post is based on https://stackoverflow.com/questions/8542864/why-use-virtual-for-class-properties-in-entity-framework-model-definitions