Подтвердить что ты не робот

EF5 ObjectContext: как заменить IQueryable <T>.Include(Path) с context.T.Attach()

Я использую Entity Framework 5 с ObjectContext в относительно большой и сложной модели данных. Я хотел бы работать с большими запросами, генерируемыми при связывании нескольких объектов IQueryable.Include(Path) с объектами, связанными с загрузкой.

Например, я делаю что-то вроде этого:

var queryPe = context.Person.Where(p => p.Id == 110).Include(@"AA");
queryPe = queryPe.Include(@"BB.CC.DD");
queryPe = queryPe.Include(@"EE.FF");

Это можно сделать общим с помощью строкового массива и привязки каждого графика во время выполнения в цикле foreach.

Вместо этого я хотел бы сделать что-то вроде этого:

Person pe = context.Person.Where(p => p.Id == 110).First();
context.LoadProperty(pe, "AA");
pe.BB.Attach(pe.BB.CreateSourceQuery().Include(@"CC.DD"));
pe.EE.Attach(pe.EE.CreateSourceQuery().Include(@"FF"));

Вместо того, чтобы иметь один большой запрос, у нас было бы 4 меньших запроса, попадающих в базу данных. Конечно, я все еще хочу использовать силу графического пути как строку.

Возможно, я ошибаюсь, но это означает, что я должен использовать relexion для получения свойств навигации по имени и выполнения CreateSourceQuery() на нем, потому что для этого не существует такого метода расширения.

Правильно ли я?

EDIT 1: У меня есть дополнительное ограничение, то есть я использую Self Tracking Entities (STE). Это означает, что Связанные объекты не реализованы как EntityCollection или EntityReference. Поэтому Attach() и CreateSourceQuery() недоступны!

Итак, я застрял в Context.LoadProperty для обработки графов объектов. Возможно ли это?

EDIT 2: проблема, обнаруженная в EDIT 1, решена благодаря использованию класса DbContext. См. Код ниже:

Person pe = context.Person.Where(p => p.Id == 110).First();
context.LoadProperty(pe, "AA");
DbContext dbc = new DbContext(context, false);
dbc.Entry(pe).Collection(@"BB").Query().Include(@"CC.DD").Load();
dbc.Entry(pe).Reference(@"EE").Query().Include(@"FF").Load();

РЕДАКТИРОВАТЬ 3 02/11/2013. Существует проблема с приведенным выше кодом (EDIT 2). Если последний объект в пути является ссылкой, а не коллекцией, код не прерывается, но он не загружается: - (

РЕДАКТИРОВАТЬ 4: вместо использования рефлексии, прямо сейчас, я генерирую код, просматривая модель данных сущности с помощью шаблона T4.

4b9b3361

Ответ 1

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

Здесь ссылка для sprocs с несколькими наборами результатов для EDMX и кода:

http://msdn.microsoft.com/en-us/data/jj691402.aspx

Ответ 2

Попробуйте разделить агрегаты в нескольких контекстах. Каждый ограниченный контекст должен иметь отдельный контекст. Таким образом, вы создаете слабо связанную инфраструктуру сущности.

У Джулии Лерман есть хорошее видео о множественном взгляде на эту концепцию.

Ответ 3

Я бы предпочел использовать хранимые процедуры. Простота обслуживания, работает быстрее и т.д.