Как работает AutoMapper с EF?
Не много не понимаю, как работает вот это:
await context.Objects
.Where(x=> x.Name!= null)
.Select(x => _mapper.Map<Object2>(x))
.Where(filter)
.ToListAsync(cancellationToken);
Фильтр — это вот это Expression<Func<Object2, bool>> filter
А именно, каким образом срабатывает AutoMapper, если запрос еще нематериализован => крутится на стороне СУБД.
Вместо х в этом месте _mapper.Map<Object2>(x), какой-то фейковый объект, который мапитья и после этого разбираются результаты мапинга и все это транслируется в Sql?
Ответы (1 шт):
Насколько я понимаю вопрос здесь есть два смысловых слоя.
Первый мне кажется вы вполне понимаете — про разницу между IEnumerable и IQueryable.
Запросы которые можно выполнить на сервере (а у вас везде так, раз вы работаете с Expression<Func) выполнятся на сервере.
Например, вот запрос:
this.EntryForms
.Where(x => x.Status == 0)
.AsEnumerable()
.Select(x => new { Id = x.Id, Json = x.Json } )
.Dump();
Смотришь в linqpad какой код - на клиент читаются все поля таблицы:
-- Region Parameters
DECLARE @p0 Int = 0
-- EndRegion
SELECT [t0].[Id], [t0].[CreateDate], [t0].[ModifyDate], [t0].[Attempts], [t0].[Status], [t0].[Json]
FROM [EntryForms] AS [t0]
WHERE [t0].[Status] = @p0
Но если убрать .AsEnumerable() с сервера читаются только два нужных на клиенте поля:
-- Region Parameters
DECLARE @p0 Int = 0
-- EndRegion
SELECT [t0].[Id], [t0].[Json]
FROM [EntryForms] AS [t0]
WHERE [t0].[Status] = @p0
Провайдер умеет разбирать expression и транслировать их в Sql. (Ну или не умеет, тогда вы получите ошибку - пример)
Второй момент (и это уже как раз про автомаппер) это то, что автомаппер при построении проекции умеет работать с Expression<Func и в частности dto'шки умеет трансформировать в выражения (тынц):
Note: This is done by converting the OrderDTO to Expression<Func<Order,bool>> and using that to find matching type in the database. You can also map objects to expressions as well.
Persist doesn't call submit changes automatically