Первая проблема кода EF - связанный объект не загружен - PullRequest
1 голос
/ 28 июля 2011

это действительно раздражает

У меня есть что-то вроде этого:

class Person {
   ..properties id, name etc..
}
class Task {
   ..properties id, name etc..
   Person Moderator {get;set}
}
public class DataModel : DbContext {
        public DbSet<Task> Tasks { get; set; }
        public DbSet<Person> People { get; set; }
}

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

Но когда я пытаюсь получить обратнозадача, объект person всегда нулевой.

using (DataModel db = new DataModel()) {
    Task t = db.Tasks.SingleOrDefault(p => p.Id == 22);
    assert(t.Name.Lenght>0)
    assert(t.Moderator != null) // always null!!!!!!
   ....
}

Что мне нужно сделать, чтобы выкупить весь граф объектов?Должен ли я сделать соединение в вызове SingleorDefault?кажется как-то не так.

Я уже говорил, что это действительно раздражает.

TIA,

Ответы [ 2 ]

3 голосов
/ 28 июля 2011

Два варианта для вас.По умолчанию модель code first / dbContext возвращает прокси-объект, производный от вашей модели (это важно понимать, когда вы сталкиваетесь с проблемами сериализации JSON).Прокси-объект использует ленивую загрузку ассоциаций, но только при определенных обстоятельствах.Свойство Moderator должно быть объявлено как виртуальное, чтобы прокси-сервер мог переопределить его и выполнить ленивую загрузку за вас.

Однако ленивая загрузка может создать проблему под названием Выберите N + 1 .Если в большинстве случаев вам нужна только Задача, а не Модератор, это не будет проблемой.Однако, если вы часто отображаете список задач и связанных с ними модераторов, вам, фактически, придется выполнять дополнительный обход в базу данных для каждой задачи в этом списке в дополнение к 1 для исходного списка (например, для списка из 100 задач).вы должны выполнить 101 запрос для отображения задач и их модераторов.

Чтобы обойти это, EF предоставляет оператор включения , который вызывает отношение к загрузке.Используйте его как таковой

Task t = db.Tasks.Include (t => t.Moderator) .SingleOrDefault (p => p.Id == 22);

Надеюсь, это поможет.

1 голос
/ 28 июля 2011

Для вашего свойства Moderator отключена отложенная загрузка, поэтому он будет загружен только в том случае, если вы явно сделаете это, используя Load().

. Вы можете принудительно загрузить EF для вашей связанной Personсущности с помощью метода Include() в вашем запросе, подобного следующему:

Task t = db.Tasks.Include(x => x.Moderator).SingleOrDefault(p => p.Id == 22)

В этой статье .

есть довольно хороший обзор.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...