#entity-framework-4.1 #ef-code-first #code-first
#entity-framework-4.1 #ef-code-first #сначала код
Вопрос:
У меня есть рассылка класса со статусом, который выглядит следующим образом:
public class Mailout
{
public int Id {get; set; }
public string Name {get; set; }
public MailoutStatus Status { get; set; }
}
public class MailoutStatus
{
public int Id { get; set; }
public string Name { get; set;}
}
Когда я вставляю рассылки и устанавливаю свойство Status, они вставляются правильно. Когда я извлекаю их, статус всегда равен null. Поскольку у меня нет (и не хочу) идентификатора статуса в моем классе рассылки, у меня нет способа восстановить его после факта. Как мне сказать EF, чтобы он заполнял это поле с готовностью, а не лениво?
Я надеюсь, что смогу что-то настроить в OnModelCreating (), поскольку я хочу такого поведения постоянно, а не как вариант, который я могу использовать иногда, манипулируя моими запросами LINQ-to-Entities.
Ответ №1:
Вам нужно сделать ваши свойства навигации виртуальными.
Комментарии:
1. @Slauma: Нет. Для корректной работы отложенной загрузки вместо возврата null. Вы можете использовать
Include(x=>x.Property)
для быстрой загрузки.2. Это был скорее риторический вопрос 😉 Потому что он сказал в вопросе, что он не хочет использовать отложенную загрузку, но нетерпеливую загрузку. Тогда создание виртуальных реквизитов не помогло бы.
3. @Slauma: вы знаете, в чем проблема XY? У пользователя проблема X, и он думает, что единственным решением является Y, поэтому он спрашивает о Y. Но реальное решение находится внутри X. Если вы внимательно прочитали его вопрос, отложенная загрузка у него не работает, поэтому он предположил, что единственный способ решить проблему — это ускорить загрузку, что не так.
4. Я знаю, что вы имеете в виду, но я прочитал вопрос по-другому. Неважно, теперь есть два ответа, которые охватывают разные интерпретации вопроса.
5. @Diego — ты молодец, и ты совершенно прав насчет моей проблемы «запрашиваю X, на самом деле нужно Y». @Slauma, спасибо также за ваш ответ!
Ответ №2:
В ModelBuilder нет такой опции, чтобы настроить автоматическую загрузку свойств навигации в каждом запросе. Вы должны указывать его запрос за запросом. В качестве обходного пути вы могли бы инкапсулировать нетерпеливую загрузку в какой-либо метод или свойство, например, в контексте:
public class MyContext : DbContext
{
public DbSet<Mailout> Mailouts { get; set; }
public IQueryable<Mailout> MailoutsWithStatus
{
get { return Mailouts.Include(m => m.Status); }
}
// ...
}
А затем использовать в ваших запросах:
context.MailoutsWithStatus.Where(...) ... etc.
Это только идея, она не проверялась.
Ответ №3:
Взяв из Employee Info Starter Kit — предстоящего выпуска MVC, вот фрагмент, который довольно хорошо работает для быстрой загрузки объектов при использовании:
public class Employee
{
...
public int? ReportsTo { get; set; }
[ForeignKey("ReportsTo")]
public virtual Employee Supervisor { get; set; }
/// <summary>
/// Children object collection of foreign key relation
/// </summary>
public virtual List<Employee> Subordinates { get; set; }
}