EF Core async client side evaluation

Working with net5.0. So I have this query:

context.DbSet
  .Where() // server side
  .AsEnumerable()
  .Where() // can't be translated to SQL so client side
  .ToList();

So how can we archieve a async variant of this? I would assume it would work like this:

await context.DbSet
  .Where() // server side
  .AsAsyncEnumerable()
  .Where() // can't be translated to SQL so client side
  .ToListAsync();

But that doesn’t work. What is the right approach?

Answer

As mentioned in the Explicit client evaluation section of the EF Core documentation, the EF Core team vision is that

If you are using AsAsyncEnumerable and want to compose the query further on client side then you can use System.Interactive.Async library which defines operators for async enumerables. For more information, see client side linq operators.

So by idea you need to install that package and use

await context.DbSet
  .Where() // server side
  .AsAsyncEnumerable()
  .Where(...) // this is provided by System.Interactive.Async
  .ToList(); // as well this

Just please note that there is some method naming clash when you reference both packages (System.Interactive.Async and Microsoft.EntityFrameworkCore, because EF Core DbSet<T> implements both IEnumerable<T> and IAsyncEnumerable<T>, which makes some extension method calls ambiguous), so you might start getting compile time errors. There are open issues in their GitHub issue trackers, but neither team is willing to fix them saying that the problem is caused by the other. One of the drawbacks of the open source policy utilized recently by Microsoft.

Leave a Reply

Your email address will not be published. Required fields are marked *