2016-08-08 6 views
2

У меня есть метод синхронизации, который я пытаюсь преобразовать в async. В принципе, приведенный ниже код проектирует данные в DTO и выбирает строки и заказывает их на основе свойств DTO. Он также получает только определенную «страницу» данных.Использование ToListAsync() с Automapper ProjectToQueryable()

return GetDbContext().Items 
      .ProjectToQueryable<DTO>(automapperConfigProvider) 
      .Where({expression based on DTO}) 
      .OrderBy({expression based on DTO}).ThenBy(...) 
      .Skip(skip) 
      .Take(take) 
      .ToList(); 

Я попытался преобразовать это так, но он не на ToListAsync.

var query = GetDbContext().Items 
      .ProjectToQueryable<DTO>(automapperConfigProvider) 
      .Where({expression based on DTO}) 
      .OrderBy({expression based on DTO}).ThenBy(...) 
      .Skip(skip) 
      .Take(take); 
return await query.ToListAsync(); 

Исключение я получаю:

Источник IQueryable не реализует IDbAsyncEnumerable. Только те источники, которые реализуют IDbAsyncEnumerable, могут использоваться для асинхронных операций Entity Framework. Для получения дополнительной информации см. http://go.microsoft.com/fwlink/?LinkId=287068.

Я использую EntityFramework, поэтому ссылка в исключении не имеет смысла для меня.

С кем это столкнулось?

ответ

0

Для тех, кто читает этот вопрос, вот как я преобразовал мой метод асинхронный:

return await GetDbContext().Items 
       .ProjectTo<DTO>(automapperConfigProvider) 
       .Where() 
       .Decompil‌​eAsync() 
       .OrderBy().ThenBy(...) 
       .Skip(skip).Take(take) 
       .ToListAsync(); 

В принципе, я хотел сервер данных, чтобы сделать всю работу в оба проектировании набор данных для DTO и выполнение запроса, а затем выбор только подмножества результата на основе информации поискового вызова.

Я исследовал вариант UseAsDataSource(), который Джимми Богард упомянул в своем комментарии к ответу Дарси. Но я использовал AutoMapper Profile в качестве поставщика конфигурации для моего сопоставления, и я не мог понять, как его преобразовать в IMapper, чтобы перейти к UseAsDataSource(). Таким образом, я оказался не таким, как предложил Джимми.

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

1

Это потому, что ProjectToQueryable<T> не реализует IDbAsyncEnumerable.

Однако есть асинхронный эквивалент .ProjectToListAsync<T>(); в пакете AutoMapper.EF6.

Подробности здесь: https://github.com/AutoMapper/AutoMapper.EF6

+0

'.ProjectToListAsync ()' не соответствует тому, что я хочу сделать, так как он будет загружать все данные в память перед my 'Where()'. Представляется, что проблема связана с ** DelegateDecompiler.EntityFramework **, которую использует ** AutoMapper.EF6 **. Аналогичная проблема была обсуждена [здесь] (https://github.com/hazzik/DelegateDecompiler/issues/24). Но исправление должно быть в пакете nuget, который я загрузил. Просто не уверен, почему это все еще проблема, или если это та же проблема. У меня не было возможности взглянуть. –

+0

@FrankFajardo как работа вокруг вы можете поставить предложение 'Where()' перед '.ProjectToListAsync ()' – DarcyThomas

+1

Я так не думаю? Я использую пакет декомпилятора делегатов EF, который исправил проблему. Но другой вариант - метод UseAsDataSource, который переводит выражения обратно в EF-модель, чтобы EF обрабатывал запросы перед проекцией. –

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