2015-03-13 3 views
0

У меня проблема с запросом linq, когда я не использую явно свойство include для свойства навигации.linq entity framework содержит странное поведение

---Task entity model ---- 
... 
public Project Project { get; set; } 
public TaskType TaskType { get; set; } 
... 

var tasks = db.Tasks 
     .Where(t => (t.Project.ProjectId == project.ProjectId)) 


foreach (Task t in tasks) 
{ 
// for some items t.TaskType is null 


// I have noticed that when t.TaskType.Id 
// is different to the first one in the loop then only the next different 
// tasktype is null 

} 


// however when using 
var tasks = db.Tasks.Include(t=>t.TaskType) 
     .Where(t => (t.Project.ProjectId == project.ProjectId))   
// tasktype is always there (where as without the include in some tasks it does not extract the tasktype) 

Использование .Include исправил мою проблему, но мне нравится понимать, почему она ведет себя так.

ответ

0

Если вы используете Eager Loading в EF, свойства навигации не загружаются с помощью корневого объекта. Метод Include инструктирует EF, что свойство навигации должно быть загружено вашим корневым объектом.

С ленивой загрузкой загруженного навигационного объекта, когда вы называете это свойство, поэтому, если вы используете ленивую нагрузку, то метод Include не нужен.

Подробнее here

+0

Будет ли он охотно загружать навигационные свойства только для некоторых предметов, а не для других? Я прохожу через цикл foreach, как указано выше, и некоторые задачи не включают в себя типы задач. Я ожидал бы, что поведение нетерпеливой нагрузки будет последовательным. – wfquestions

+0

@wfquestions Перед 'var tasks = db.Tasks.Where (t => (t.Project.ProjectId == project.ProjectId))' запрос, как вы используете экземпляр 'db'' DbContext'? Возможно, вы добавляете некоторые «Задачи» в этот экземпляр «DbContext»? –

0

Я думаю, что вы ищете ленив нагрузки соответствующие объекты. Для этого вам необходимо указать свои навигационные свойства как virtual. Из этого page:

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

Когда вы указываете ключевое слово virtual в своих навигационных свойствах, EF создает динамические прокси во время выполнения для ваших классов сущностей. Эти прокси-классы отвечают за ленивое поведение загрузки связанных объектов. Без виртуальной, ленивой загрузки не будет поддерживаться, и вы получите нулевое значение в свойствах навигации. Так что вам нужно сделать, это:

public class Task 
{ 
    //... 
    public virtual Project Project { get; set; } 
    public virtual TaskType TaskType { get; set; } 
{ 

В этом link вы найдете все requiriments нужно следовать, чтобы поддерживать отложенную загрузку.

Используя метод Include, вы можете запросить загрузку связанных объектов как часть запроса.

Смежные вопросы