Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

navigation property should be virtual - not required in ef core?

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?

like image 842
Alexan Avatar asked Jan 26 '17 19:01

Alexan


People also ask

Why is navigation property virtual?

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.

What is navigation property in Entity Framework Core?

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)

What benefit do you get from declaring entity navigation properties as virtual?

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.

What is lazy loading EF core?

Lazy loading means that the related data is transparently loaded from the database when the navigation property is accessed.


2 Answers

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.

like image 60
Ivan Stoev Avatar answered Oct 11 '22 02:10

Ivan Stoev


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.

like image 32
Matt Avatar answered Oct 11 '22 03:10

Matt