свойство навигации должно быть виртуальным – не требуется в ef core?

Как я помню, в EF свойство навигации должно быть виртуальным :

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 Posts { get; set; } } 

Но я смотрю на EF Core и не вижу его виртуальным:

 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 Enrollments { get; set; } } 

Больше не требуется?

virtual никогда не требовалось в EF. Это было необходимо, только если вам нужна ленивая поддержка загрузки.

Поскольку Lazy loading еще не поддерживается EF Core , в настоящее время virtual имеют особого значения. Когда (и если) они добавят ленивую поддержку загрузки (есть план для этого).

Обновление: начиная с EF Core 2.1, теперь поддерживается Lazy . Но как только вы не добавите пакет Microsoft.EntityFrameworkCore.Proxies и включите его с помощью UseLazyLoadingProxies , исходный ответ по-прежнему применяется.

Однако, если вы это сделаете, ситуация полностью изменится из-за отсутствия контроля выбора в начальной реализации – для этого все ваши свойства навигации будут virtual . Для меня это не имеет смысла, вам лучше не использовать это, пока он не будет исправлен. Если вам действительно нужна ленивая загрузка, используйте альтернативную ленивую загрузку без подхода прокси , и в этом случае снова virtual не имеет значения.

Все изменилось с момента написания принятого ответа. В 2018 году Lazy Loading теперь поддерживается как платформа Entity Framework Core 2.1 для двух разных подходов.

Простейший способ использования двух – использование прокси, и для этого потребуются требуемые ленивые свойства для определения virtual . Чтобы процитировать ссылку на связанную страницу:

Самый простой способ использования ленивой загрузки – установить пакет Microsoft.EntityFrameworkCore.Proxies и включить его с вызовом UseLazyLoadingProxies . […] EF Core затем включит lazy-load для любого свойства навигации, которое можно переопределить, то есть оно должно быть виртуальным и в classе, который может быть унаследован.

И вот приведенный пример кода:

 public class Blog { public int Id { get; set; } public string Name { get; set; } public virtual ICollection 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; } } 

Существует еще один способ делать Lazy Loading без прокси, который должен ILazyLoader в конструктор типа данных. Это объясняется здесь .

Короче говоря, существует два способа выполнения Lazy Loading: с прокси и без них. virtual требуется, если и только если вы хотите поддерживать Lazy Loading с помощью прокси. В противном случае это не так.

Виртуальное ключевое слово никогда не требовалось … Это необязательно.

Что это изменит?

1. если вы объявите свою собственность виртуальной:

Ваше виртуальное свойство (по умолчанию) сразу не будет загружено при запросе основного объекта. Он будет извлекаться из базы данных ТОЛЬКО, если вы попытаетесь получить к нему доступ или обратитесь к одному из его компонентов.

И это называется ленивой загрузкой.

2. если вы объявите его не виртуальным:

Ваша собственность будет (по умолчанию) загружаться сразу же вместе со всем другим свойством в вашей основной сущности. Это означает, что ваша собственность будет готова к доступу: она уже была удалена. Сущность не будет запрашивать повторно базу данных, потому что вы получаете доступ к этому свойству.

Это называется нетерпением загрузки.

Мое мнение :

Чаще всего я выбираю с нетерпением загрузку (не виртуальную), потому что большую часть времени мне нужно каждое свойство каждого объекта, которое будет использоваться без запроса назад (быстрее в случае, если вы действительно хотите все быстро), но если вы получите доступ к этому свойству только время от времени (ваш листинг ничего), и вы хотите чаще всего остальную информацию, кроме ЭТОГО, а затем сделать ее виртуальной, чтобы это свойство не замедляло остальную часть запроса только для небольшого доступа.

Надеюсь, это было ясно …

Примеры:

Где я бы не использовал виртуальный (с нетерпением):

 foreach(var line in query) { var v = line.NotVirtual; // I access the property for every line } 

Где бы я использовал виртуальную или ленивую загрузку:

 foreach(var line in query) { if(line.ID == 509) // because of this condition var v = line.Virtual; // I access the property only once in a while } 

одна последняя вещь :

Если вы не запрашиваете более 1000 строк базы данных, то все, что вы выберете, не будет иметь большого эффекта. Кроме того, вы можете объявить это свойство виртуальным, и если вы хотите протестировать наоборот, вам просто нужно сделать это:

 context.LazyLoadingEnabled = false; 

Он отменяет виртуальный эффект.

редактировать

Для более новых версий EF:

 WhateverEntities db = new WhateverEntities() db.Configuration.LazyLoadingEnabled = false; 

В EF Core по умолчанию выбрал путь обескураживания ленивой загрузки. Также я думаю, что эта функция по-прежнему не реализована после этой проблемы.

https://github.com/aspnet/EntityFramework/issues/3312

В предыдущих версиях EF свойства виртуальной навигации позволяли ленить нагрузку на связанные объекты.

Я думаю, что загрузка свойств навигации на данный момент может быть достигнута только с помощью .Include(...)

РЕДАКТИРОВАТЬ:

Существует несколько способов загрузки связанных объектов, которые поддерживаются в Core. Если вас это интересует: https://docs.microsoft.com/en-us/ef/core/querying/related-data

Обновление: первоначальная реализация ленивой загрузки, запланированная для EF Core 2.1, потребует, чтобы свойства навигации объявлялись виртуальными. См. https://github.com/aspnet/EntityFrameworkCore/issues/10787 и, в более общем плане, для отслеживания прогресса по ленивой загрузке, см. https://github.com/aspnet/EntityFrameworkCore/issues/10509 .

  • Передайте строку соединения кодовому первому DbContext
  • Entity Framework с NOLOCK
  • Первые таблицы переходов EF5 и таблицы поиска
  • Установите десятичное значение (16, 3) для столбца в первом подходе кода в EF4.3
  • Как хранить изображения с использованием кода Entity Framework First CTP 5?
  • EF 4.1 загрузка фильтрованных дочерних коллекций, не работающих для многих-ко-многим
  • Код структуры Entity Framework Сначала используйте Guid как идентификатор с другой колонкой Identity
  • Как передать параметры методу DbContext.Database.ExecuteSqlCommand?
  • Как обновлять не все поля объекта с использованием Entity Framework и EntityState.Modified
  • Как мне сначала разделить мои таблицы в EF Code?
  • От многих до многих сопоставление с дополнительными полями в Fluent API
  • Давайте будем гением компьютера.