Frank Fajardo Frank Fajardo - 3 months ago 70
C# Question

Using ToListAsync() with Automapper ProjectToQueryable()

I have a sync method which I'm trying to convert to async. Basically, the code below projects the data into a DTO, and selects rows and orders them based on properties of the DTO. It also gets only a certain 'page' of the data.

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


I tried to convert it like this but it fails on the
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();


The exception I get is:

The source IQueryable doesn't implement IDbAsyncEnumerable. Only sources that implement IDbAsyncEnumerable can be used for Entity Framework asynchronous operations. For more details see http://go.microsoft.com/fwlink/?LinkId=287068.

I'm using EntityFramework, so the link in the exception does not make sense to me.

Has anyone encountered this?

Answer

For anyone reading this question, here is how I converted by method to async:

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

Basically, I wanted the data server to do all the work in both projecting the dataset to DTO, and performing the query, and then picking only a subset of the result based on paging information.

I explored the UseAsDataSource() option which Jimmy Bogard mentioned in his comment to Darcy's answer. But I was using an AutoMapper Profile as a configuration provider for my mapping, and I could not quite figure out how to convert that to an IMapper to pass to UseAsDataSource(). So I ended up not doing as Jimmy suggested.

I'm sure there are other ways one could resolve this, but I did it through the code above.

Comments