Entity Framework Code First Lazy Загрузка
У меня есть два класса объектов
public class User
{
public Guid Id { get; set; }
public string Name { get; set; }
// Navigation
public ICollection<Product> Products { get; set; }
}
public class Product
{
public Guid Id { get; set; }
// Navigation
public User User { get; set; }
public Guid User_Id { get; set; }
public string Name { get; set; }
}
Когда я загружаю пользователя, использующего dataContext, я получаю список нулевых продуктов (это нормально).
Если я добавлю "виртуальное" ключевое слово в список продуктов,
public virtual ICollection<Product> Products { get; set; }
когда я загружаю пользователя, я также получаю список продуктов.
Почему это происходит? Я думал, что ключевое слово "virtual" используется для того, чтобы не загружать объекты, если вы не указали это (используя инструкцию "Include" )
Я думаю, что все неправильно.
Ответы
Ответ 1
Это неверно
"виртуальное" ключевое слово используется для того, чтобы не загружать объекты, если вы не явно это (используя инструкцию "Включить" )
Lazy Loading означает, что объекты будут автоматически загружены при первом доступе к свойству коллекции или навигации, и это произойдет прозрачно, как если бы они всегда были загружены родительским объектом.
Использование "include" - загрузка по требованию при указании свойств, которые вы хотите запросить.
Существование ключевого слова virtual
связано только с ленивой загрузкой. virtual
ключевое слово позволяет среде фреймворка сущности создавать динамические прокси-серверы для ваших классов сущностей и их свойств и тем самым поддерживать ленивую загрузку. Без виртуальной, ленивой загрузки не будет поддерживаться, и вы получите null на свойства коллекции.
Факт в том, что вы можете использовать "включить" в любом случае, но без ленивой загрузки это единственный способ доступа к свойствам коллекции и навигации.
Ответ 2
Я предполагаю, что вы запрашиваете свойство, которое является предметом ленивой загрузки, находясь в контексте ef:
using (var db = new Context())
{
var user = db.Users.Where(...);
var products = user.Products; // being loaded right away
}
Попробуйте оставить его:
User user;
using (var db = new Context())
{
user = db.Users.Where(...);
// I guess you will need here:
// .Include(u => u.Products)
}
var products = user.Products; // what error will you get here?