AutoMapper ProjectTo с многоуровневым включением DbContext () - PullRequest
0 голосов
/ 14 февраля 2020

Мне нужно выполнить многоуровневый запрос Include() во время выбора EF Core. Я использую AutoMapper с ProjectTo<>().

Я указал в сопоставлениях ExplicitExpansion(), что означает, что свойства навигации не будут заполняться автоматически, потому что я хочу иметь возможность выполнять один и тот же запрос несколько раз и один раз Include() свойство навигации, но второй раз игнорировать его ,

ProjectTo<>() метод имеет параметры, которые позволяют мне включать свойства навигации в мой выбор, но мне нужно выполнить многоуровневое включение. Это возможно? Такой синтаксис, как Include(e => e.Collection.Select(sc => sc.MyProperty)), не работает в этом случае.

Я пытался использовать Include().ThenInclude() для DbContext, а затем выполнить ProjectTo, но в этом случае ProjectTo переопределяет мои включения, и они игнорируются.

Теперь я не уверен, возможно ли вообще указать ProjectTo, ExplicitExpansion() в отображении и многоуровневое включение?

Ответы [ 2 ]

0 голосов
/ 14 февраля 2020

Я попытался использовать Include (). ThenInclude () для DbContext, а затем выполнить ProjectTo, , но в этом случае ProjectTo переопределяет мои включения, и они игнорируются.

Это переопределение работает по назначению.


Select() переопределение Include()

Это явно упоминается в документации EF :

Если изменить запрос так, чтобы он больше не возвращал экземпляры типа сущности, с которого начался запрос, то операторы включения игнорируются.

В следующем примере операторы включения основаны на Blog, но затем оператор Select используется для изменения запроса на возврат анонимного типа. В этом случае операторы включения не действуют.

Включить

Include() инструктирует EF загружать некоторые связанные объекты при получении запрошенного набора результатов. Это поведение добавляется к стандартному поведению загрузки EF:

var people = db.People.ToList();

var peopleWithPets = db.People.Include(person => person.Pets).ToList();

Добавив Include(), вы существенно расширили поведение загрузки, которое происходит под капотом при перечислении коллекции (в данном случае , ToList()).

Выберите

Select() переопределяет поведение загрузки по умолчанию с новым определенным поведением.

var people = db.People.ToList();

var names = db.People.Select(person => person.Name).ToList();

Когда вы звоните Select(), вы, по сути, инструктируете EF , а не выполнять свое поведение по умолчанию (которое может включать или не включать дополнительные включения), и вместо этого загружать точно то, что вы указали (в данном случае person => person.Name).


ProjectTo<>() - это обертка вокруг Select()

Вы можете думать о ProjectTo<TDestination>() как о своего рода SelectFactory, который генерирует соответствующий оператор Select на основе сопоставления TDestination, настроенного в Automapper.
Под капотом EF по-прежнему выполняет Select(), и, следовательно, такое же поведение, как описано выше применяется при использовании ProjectTo<>().

* 1 070 * Если вы хотите включить дополнительные связанные сущности или любые их свойства, вам нужно развернуть отображение Automapper вместо использования Include в запросе. Если ваше отображение включает в себя дополнительные поля, Automapper расширит свой базовый Select() соответственно.

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

0 голосов
/ 14 февраля 2020

Вы пробовали?

dbContext.Entities.ProjectTo<EntityDto>(dest => dest.Collection.Select(item => item.MyProperty));
...