As I remember in EF navigation property should be virtual:
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; } }
But I look at EF Core and don't see it as virtual:
public class Student { public int ID { get; set; } public string LastName { get; set; } public string FirstMidName { get; set; } public DateTime EnrollmentDate { get; set; } public ICollection<Enrollment> Enrollments { get; set; } }
Is it not required anymore?
If you define your navigation property virtual , Entity Framework will at runtime create a new class (dynamic proxy) derived from your class and uses it instead of your original class. This new dynamically created class contains logic to load the navigation property when accessed for the first time.
A navigation property is an optional property on an entity type that allows for navigation from one end of an association to the other end. Unlike other properties, navigation properties do not carry data. A navigation property definition includes the following: A name. (Required)
In Entity Framework, using a virtual navigation property allows you to denote it as the equivalent of a nullable Foreign Key in SQL. You do not HAVE to eagerly join every keyed table when performing a query, but when you need the information -- it becomes demand-driven.
Lazy loading means that the related data is transparently loaded from the database when the navigation property is accessed.
virtual
was never required in EF. It was needed only if you want lazy loading support.
Since Lazy loading is not yet supported by EF Core, currently virtual
have no special meaning. It would when (and if) they add lazy loading support (there is a plan for doing so).
Update: Starting with EF Core 2.1, Lazy loading is now supported. But if you don't add Microsoft.EntityFrameworkCore.Proxies package and enable it via UseLazyLoadingProxies
, the original answer still applies.
However if you do so, the thing's totally changed due to the lack of the opt-in control in the initial implementation - it requires all your navigation properties to be virtual
. Which makes no sense to me, you'd better not use that until it gets fixed. If you really need lazy loading, use the alternative Lazy loading without proxies approach, in which case again virtual
doesn't matter.
Things have changed since the accepted answer was written. In 2018, Lazy Loading is now supported as of Entity Framework Core 2.1 for two different approaches.
The simpler way of the two is using proxies, and this will require the properties desired to be lazily loaded to be defined with virtual
. To quote from the linked page:
The simplest way to use lazy-loading is by installing the Microsoft.EntityFrameworkCore.Proxies package and enabling it with a call to
UseLazyLoadingProxies
. [...] EF Core will then enable lazy-loading for any navigation property that can be overridden--that is, it must be virtual and on a class that can be inherited from.
And here is the provided sample code:
public class Blog { public int Id { get; set; } public string Name { get; set; } public virtual ICollection<Post> Posts { get; set; } } public class Post { public int Id { get; set; } public string Title { get; set; } public string Content { get; set; } public virtual Blog Blog { get; set; } }
There is another way of doing Lazy Loading without proxies, which is to inject ILazyLoader
into the constructor of the data type. This is explained in here.
In short, there are two ways to perform Lazy Loading: with and without proxies. virtual
is required if and only if you wish to support Lazy Loading with proxies. Otherwise, it is not.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With