65

I am using a LINQ query on a DbSet<T>:

await _dbContext.Users.AnyAsync(u => u.Name == name);

However, the compiler outputs the following error:

Error CS0121: The call is ambiguous between the following methods or properties:
'System.Linq.AsyncEnumerable.AnyAsync<TSource>(System.Collections.Generic.IAsyncEnumerable<TSource>, System.Func<TSource, bool>)' and
'Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.AnyAsync<TSource>(System.Linq.IQueryable<TSource>, System.Linq.Expressions.Expression<System.Func<TSource, bool>>)'

A similar problem also occurs with other LINQ extension methods, like .Where().

I am using EF.Core 3.1 and have the System.Linq.Async package installed. How do I fix this issue?

0

1 Answer 1

128

The described problem is caused by using the System.Linq.Async package along with the DbSet<TEntity> class.

Since DbSet<TEntity> implements both IQueryable<TEntity> and IAsyncEnumerable<TEntity>, importing the namespaces System.Linq and Microsoft.EntityFrameworkCore leads to the definition of the conflicting extension methods. Unfortunately, avoiding importing one of them is usually not practicable.

This behavior is present beginning with EF.Core 3.0, and is discussed in this issue.

In order to address this, EF.Core 3.1 adds two auxiliary functions AsAsyncEnumerable() and AsQueryable(), which explicitly return the respective interfaces IAsyncEnumerable<TEntity> or IQueryable<TEntity>.

The given code sample is fixed by calling the desired disambiguation function:

await _dbContext.Users.AsQueryable().AnyAsync(u => u.Name == name);

or

await _dbContext.Users.AsAsyncEnumerable().AnyAsync(u => u.Name == name);

Note that AsAsyncEnumerable() forces client-side evaluation of AnyAsync(). So the entire Users table will be fetched into memory.

Sign up to request clarification or add additional context in comments.

2 Comments

Just wondering, is there difference (performance or otherwise) between the 2 workarounds that you showed?
@GregZ. The performance impact is no different from a regular C# cast: AsQueryable() and AsAsyncEnumerable() simply perform a cast to their respective interfaces. AsQueryable() just casts this to (IQueryable<TEntity>) this, and AsAsyncEnumerable() casts this to (IAsyncEnumerable<TEntity>)this.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.