Given this code
using System.Linq;
using Microsoft.EntityFrameworkCore;
var agencies = await dbContext.Agencies.ToListAsync();
Where dbContext.Agencies is a DbSet<T>
If i add the System.Linq.Async nuget to the project it now breaks the build
CS0121 The call is ambiguous between the following methods or properties:
'System.Linq.Queryable.Where<TSource>(System.Linq.IQueryable<TSource>, System.Linq.Expressions.Expression<System.Func<TSource, bool>>)'
and
'System.Linq.AsyncEnumerable.Where<TSource>(System.Collections.Generic.IAsyncEnumerable<TSource>, System.Func<TSource, bool>)
Now this can be worked around by doing a static invoke:
var agencies = await EntityFrameworkQueryableExtensions.ToListAsync(dbContext.Agencies);
But as you can see this makes it very verbose. And the above is for a simple example.
A more complex one translates as follows
var x = await ReportAccessView
.Where(p => p.ReportId == reportId && p.UserId == userId )
.Select(p => p.AccessRights)
.ToListAsync();
var x = await EntityFrameworkQueryableExtensions
.ToListAsync(
Queryable
.Select(
Queryable
.Where(ReportAccessView, p => p.ReportId == reportId && p.UserId == userId), p => p.AccessRights));
Just wondering if there are any thoughts on handling this in a more graceful way?
/cc @bartdesmet ?
I am assuming the only fix would be for EF to not use extension methods for linq methods on types they own?
This is one of the unfortunate drawbacks of extension methods on interfaces. The moment someone implements multiple interfaces which both have extension methods defined, ambiguities can arise.
In this case, the use of AsQueryable may provide a solution, by "casting away" the IAsyncEnumerable<T> nature of DbSet<T> and only retaining IQueryable<T>:
var x = await ReportAccessView.AsQueryable()
.Where(p => p.ReportId == reportId && p.UserId == userId )
.Select(p => p.AccessRights)
.ToListAsync();
It also make it clearer what's happening remotely, versus locally.
@bartdesmet thanks. worked perfectly
ok i think this should be re-opened.
I was ok with the .AsQueryable() workaround in a top level app. since this is decision we can make as a team owning the app. But i am now in the position where i want to include System.Linq.Async as a nuget dependency in a library. I dont think i should be dictating to all users of my lib that they also need to use the .AsQueryable() workaround
thoughts?
This is still a design issue with EF core in the way they鈥檝e chosen to implement the interfaces. I don鈥檛 think there鈥檚 anything we can do here.
sigh. u r correct :(
Wouldn't it help if this library used a namespace other than System.Linq?
Most helpful comment
Wouldn't it help if this library used a namespace other than
System.Linq?