2

When watching some of the Entity Framework tutorials, I see that there are many ways for creating relationships between two Entities. But its hard for me to understand the exact meaning of these lines.

public virtual Person person { set; get; }

public virtual IEnumerable<Person> person { set; get; }

public virtual ICollection<Person> person { set; get; }

In one of the videos they explain that when you create a property that is virtual and ICollection at the same time then this enables lazy loading

What does the virtual keyword do in this instance and what would happen if we try this without virtual keyword?

nathan gonzalez
  • 11,817
  • 4
  • 41
  • 57
Ankit Agrawal
  • 325
  • 2
  • 5
  • 16

2 Answers2

3

EF needs to implement the classes as virtual because the proxy is created as a inherited class in run-time. What the lazy load engine does is to reimplement (override) these properties in the backstage to work as expected. The virtual keyword does exactly it: allow other classes to override its implementation. That is basically the reason why you need these properties virtual if you want Lazy Load enabled and working.

You'll notice that when lazy loading is enabled, the name of the intances you get in run-time are weird like "Person_Proxy987321654697987465449".

Regarding relationships, whenever you create a entity that has for instance a 1:N relationship in the database, you can have a collection that EF automatically list its relations, so you can use it in your code like this example, supposing a "Person 1:N Orders":

var ordersFromSomePerson = person.Orders;

natenho
  • 5,231
  • 4
  • 27
  • 52
0

In order to answer the question about why the virtual ICollection enables lazy loading in EF, we need the definition and meaning of the virtual keyword in C#. From MSDN:

The virtual keyword is used to modify a method, property, indexer or event declaration, 
and allow it to be overridden in a derived class. For example, this method can be 
overridden by any class that inherits it.

It is a part of the inheritance mechanism from the Object Oriented Programming concept.

It is often the case, that a sub-class needs another (extended) functionality as the base class. In such case the virtual keyword allows the programmer to override ( the default implementation of the base class for this current implementation if desired, but all other predefined methods/properties/etc. are still taken from the base class!

A simple example would be:

// base digit class
public class Digit
{
    public int N { get; set; }
    // default output
    public virtual string Print()
    {
        return string.Format("I am base digit: {0}", this.N);
    }
}

public class One : Digit
{
    public One()
    {
        this.N = 1;
    }
    // i want my own output
    public override string Print()
    {
        return string.Format("{0}", this.N);
    }
}

public class Two : Digit
{
    public Two()
    {
        this.N = 2;
    }
    // i will use the default output!
}

When two objects are created and Print is called:

var one = new One();
var two = new Two();
System.Console.WriteLine(one.Print());
System.Console.WriteLine(two.Print());

The output is:

1
I am base digit: 2

The lazy evaluation in EF comes not from the virtual keyword direct, but from the override possibility that the keyword enables (again from MSDN on Lazy Loading):

When using POCO entity types, lazy loading is achieved by creating 
instances of derived proxy types and then overriding virtual 
properties to add the loading hook.

When the predefined methods are overriden, then the programmer could enable lazy loading!

keenthinker
  • 7,645
  • 2
  • 35
  • 45