In this article, we will learn when the “call is ambiguous” error happens, why the error happens, and how to work around the issue. There are still so many legacy projects using older versions of EF Core, and in those projects, this error can cause a lot of headaches for developers if they are not aware of how to resolve it.
So, let’s start and see what we can do about it.
When Does the Issue Happen?
One example is when we use
Entity Framework Core version 5 and
System.Linq.Async Nuget packages.
Entity Framework Core version 6 or later package already resolves the issue, and we will explain that later in this article.
The sample application is a
.NET 7 console application and it has both
Entity Framework Core (EF Core) version 5 and
System.Linq.Async version 6 libraries.
So, let’s start with querying the
DbSet from the
blogDbContext.Articles.Where(x => x.Title == "Some Title");
Right after we write the code, we see the “call is ambiguous” error message on the
Why Does the Issue Happen?
The issue happens when an instance of the class has more than one method with the same name. But how can an instance have more than one method with the same name? The answer is – The C# extension method feature.
By using the feature, we can add custom methods to existing interfaces and classes. If you are unfamiliar with the feature, please refer to the Static Members, Constants and Extension Methods in C# article.
Multiple Where Methods in the Interface
Now, let’s inspect the interfaces that contain the
Where method to the
IQueryable<TSource> interface. Similarly, the
System.Linq.Async library adds
Where method to the
DbSet<TEntity> class inherits from both
IAsyncEnumerable<TEntity> interfaces. As a result, the
DbSet<TEntity> class ends up having two
This also applies to other methods such as
FirstOrDefaultAsync, etc. Of course, the cause and the solutions are the same as for the
Where method, so we will focus on the
Where method’s case in this article.
How to Work Around the Issue?
There are several ways to work around the issue.
Use Explicit Casting
The first workaround is to use the explicit cast.
Let’s change the code:
((IQueryable<Article>)blogDbContext.Articles).Where(x => x.Title == "Some Title");
Because we explicitly cast the
IQueryable<Article>, the compiler knows which
Where method to use.
Let’s try to cast to another interface as well:
((IAsyncEnumerable<Article>)blogDbContext.Articles).Where(x => x.Title == "Some Title");
Again, we don’t encounter the error.
Use AsQueryable And AsAsyncEnumerable Methods
Entity Framework Core library provides
AsAsyncEnumerable methods to work around the issue so that we don’t need to use the explicit cast:
blogDbContext.Articles.AsQueryable().Where(x => x.Title == "Some Title"); blogDbContext.Articles.AsAsyncEnumerable().Where(x => x.Title == "Some Title");
Both methods work as expected and we don’t encounter the issue. Basically, what this does is the same with explicit casting, but the code is more clear with fewer parenthesis!
Upgrade to Entity Framework Core Version 6 or Later
Entity Framework Core 6, the
IAsyncEnumerable<TEntity> interface inheritance was removed from the
DbSet class. Therefore, if we upgrade the version of EF Core, we won’t encounter this ambiguity issue anymore.
In this article, we’ve learned when and why the “call is ambiguous” issue happens. Whenever you encounter the same issue in the future, we hope this article helps you to solve the issue.