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

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

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

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

Ответ 1

До сих пор я знаю об этих эффектах.

  • Lazy Loading: Любой virtual ICollections будет лениво загружен, если вы специально не отметили их иначе.
  • Более эффективное отслеживание изменений. Если вы отвечаете всем следующим требованиям, ваше отслеживание изменений может использовать более эффективный метод, подключив ваши виртуальные свойства. По ссылке:

    Чтобы получить прокси-серверы отслеживания изменений, основное правило: ваш класс должен быть публичный, не абстрактный или непечатаемый. Ваш класс должен также виртуальные геттеры/сеттеры для всех свойства, которые сохраняются. Наконец, вы должны объявить коллекцию ориентированная связь свойства только ICollection<T>. Они не могут быть конкретными реализация или другой интерфейс которая вытекает из ICollection<T> (a отличие от отложенной загрузки прокси)

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

Ответ 2

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

Вы должны использовать ключевое слово 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; }  
}

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

Если ленивая загрузка выключена, загрузка коллекции сообщений может быть достигнута с использованием нетерпеливой загрузки (с использованием метода 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(); 
}