Какой эффект может иметь ключевое слово virtual в Entity Framework 4.1 POCO Code First?

Влияет ли ключевое слово virtual при использовании в свойствах в EF Code First ?. Может ли кто-нибудь описать все его разветвления в разных ситуациях?

Например, я знаю, что он может управлять lazy loading - если вы используете ключевое слово virtual в свойстве отношения ICollection / один-ко-многим, оно будет загружаться лениво по умолчанию, тогда как если вы оставите ключевое слово virtual , он будет загружен с нетерпением.

Какие еще эффекты может иметь ключевое слово virtual в EF с сущностями POCO ?. Должен ли я использовать virtual по умолчанию для всех моих свойств или по умолчанию не использовать его?


person Scott Stafford    schedule 08.04.2011    source источник


Ответы (2)


Пока я знаю об этих эффектах.

  • Ленивая загрузка: любые virtual ICollections будут загружаться отложенно, если вы специально не отметите их иначе.
  • # P2 #
    # P3 #

Еще одна полезная ссылка с описанием этого - Требования для создания прокси-серверов POCO от MSDN.

person Scott Stafford    schedule 08.04.2011
comment
Других причин делать свойства виртуальными нет. Свойства навигации помечены как виртуальные для отложенной загрузки, а скалярные свойства помечены как виртуальные для отслеживания изменений. - person Ladislav Mrnka; 08.04.2011
comment
что такое свойства навигации и что такое скалярные свойства? - person Abid Ali; 10.07.2012
comment
@AbidAli: Я считаю, что свойство навигации - это внешний ключ (тип класса сущности) или отношение «один ко многим» (типа ICollection ‹›). Скалярное свойство - это базовый тип (int, string, ..) или ComplexType (который является просто структурой базовых типов). - person Scott Stafford; 18.07.2012
comment
public virtual byte[] bigData { get; set; } ленивая загрузка? - person AechoLiu; 14.06.2013
comment
bytes [] будет загружен с нетерпением, только внешние ключи могут быть ленивыми. Если вы не хотите получать этот столбец, никогда не извлекайте всю запись - просто .Select(a=>new { fields you want }). - person Scott Stafford; 14.06.2013
comment
Это действительно лучший ответ? - person Tom Stickel; 08.03.2017
comment
как явно пометить виртуал как не загружаемый ленивым? - person Pétur Ingi Egilsson; 21.04.2017

Это ключевое слово virtual связано с темой загрузки данных из структуры сущностей (отложенная загрузка, активная загрузка и явная загрузка).

Вы должны использовать ключевое слово virtual, когда вы хотите загружать данные с отложенной загрузкой.

ленивая загрузка - это процесс, при котором сущность или набор сущностей автоматически загружается из базы данных при первом обращении к ней.

Например, при использовании класса сущности Blog, определенного ниже, связанные сообщения будут загружены при первом доступе к свойству навигации по сообщениям:

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

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

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

Жадно загружается:

using (var context = new BloggingContext()) 
{ 
    // Load all blogs and related posts 
    var blogs1 = context.Blogs 
                          .Include(b => b.Posts) 
                          .ToList(); 
}

Явная загрузка:

using (var context = new BloggingContext()) 
{ 
    var blog = context.Blogs.Find(1); 

    // Load the posts related to a given blog 
    context.Entry(blog).Collection(p => p.Posts).Load(); 
}
person Parsa    schedule 06.01.2016
comment
Как избежать проблемы N + 1 при использовании виртуальной (ленивой загрузки)? Например, context.Blogs.ToList (); тогда он не будет присоединяться к таблицам и будет выполнять запрос выбора столько же, сколько и количество блогов. - person Expert wanna be; 30.06.2016
comment
@Expertwannabe Даже если вы используете отложенную загрузку, вы все равно можете явно запросить активную загрузку с помощью вызова Include(). - person Monsignor; 14.03.2018