Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The call is ambiguous between the following methods or properties (IAsyncEnumerable, IQueryable) #18220

Closed
NicolasDorier opened this issue Oct 4, 2019 · 8 comments

Comments

@NicolasDorier
Copy link

In .NET Core 3.0, my code which worked in 2.1 does not compile anymore:

The call is ambiguous between the following methods or properties: 'System.Linq.AsyncEnumerable.Where<TSource>(System.Collections.Generic.IAsyncEnumerable<TSource>, System.Func<TSource, bool>)' and 'System.Linq.Queryable.Where<TSource>(System.Linq.IQueryable<TSource>, System.Linq.Expressions.Expression<System.Func<TSource, bool>>)'

This is the case of a simple dbset.Where

My usings:

using BTCPayServer.Data;
using DBriize;
using NBitcoin;
using NBitcoin.DataEncoders;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Query;
using System.Linq;

If I remove System.Linq, then it does not find Where.

@NicolasDorier
Copy link
Author

So the problem is that there is lot's of conflict between System.Linq and Microsoft.EntityFrameworkCore extensions in 3.0.

This simply makes it impossible to use both in the same file without massive headache or using unreadable static methods...

@NicolasDorier
Copy link
Author

And if you remove using Microsoft.EntityFrameworkCore and use AsAsyncEnumerable(), then of course, you can't use .Include on your DBSet.

@NicolasDorier
Copy link
Author

NicolasDorier commented Oct 4, 2019

The workaround is to put extensions methods at the root of your project.

public static IAsyncEnumerable<TEntity> AsAsyncEnumerable<TEntity>(this Microsoft.EntityFrameworkCore.DbSet<TEntity> obj) where TEntity : class
{
        return Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.AsAsyncEnumerable(obj);
}
public static IQueryable<TEntity> Where<TEntity>(this Microsoft.EntityFrameworkCore.DbSet<TEntity> obj, System.Linq.Expressions.Expression<Func<TEntity, bool>> predicate) where TEntity : class
{
    return System.Linq.Queryable.Where(obj, predicate);
}

It solves conflicts because it seems the compiler prefer the extension method inside the current namespace before the usings one... this is shitty situation though.

@smitpatel
Copy link
Contributor

@NicolasDorier - If your intention to use EF method can just call AsQueryable on DbSet.

@smitpatel
Copy link
Contributor

Closing as same root cause as #18124

@c5racing
Copy link

c5racing commented Sep 29, 2020

The workaround is to put extensions methods at the root of your project.

public static IAsyncEnumerable<TEntity> AsAsyncEnumerable<TEntity>(this Microsoft.EntityFrameworkCore.DbSet<TEntity> obj) where TEntity : class
{
        return Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.AsAsyncEnumerable(obj);
}
public static IQueryable<TEntity> Where<TEntity>(this Microsoft.EntityFrameworkCore.DbSet<TEntity> obj, System.Linq.Expressions.Expression<Func<TEntity, bool>> predicate) where TEntity : class
{
    return System.Linq.Queryable.Where(obj, predicate);
}

It solves conflicts because it seems the compiler prefer the extension method inside the current namespace before the usings one... this is shitty situation though.

Afer adding this, I receive the following error:

Expression of type 'Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable1[Titan.Dal.Ingredient]' cannot be used for parameter of type 'Microsoft.EntityFrameworkCore.DbSet1[Titan.Dal.Ingredient]' of method 'System.Linq.IQueryable1[Titan.Dal.Ingredient] Where[Ingredient](Microsoft.EntityFrameworkCore.DbSet1[Titan.Dal.Ingredient], System.Linq.Expressions.Expression1[System.Func2[Titan.Dal.Ingredient,System.Boolean]])'

This doesn't work:

        IQueryable<SearchItemResponseDataModel> items = from item in db.Item
                                                                from e in db.Recipe.Where(a => a.ItemId == item.ItemId).DefaultIfEmpty()
                                                                select new SearchItemResponseDataModel
                                                                {
                                                                    ItemId = item.ItemId,
                                                                    Identifier = item.Identifier,
                                                                    Name = item.Name,
                                                                    IsActive = item.IsActive,
                                                                    Description = item.Description
                                                                };

This does:

           IQueryable<SearchItemResponseDataModel> items = from item in db.Item.AsQuerable()
                                                            from e in db.Recipe.AsQuerable().Where(a => a.ItemId == item.ItemId).DefaultIfEmpty()
                                                            select new SearchItemResponseDataModel
                                                            {
                                                                ItemId = item.ItemId,
                                                                Identifier = item.Identifier,
                                                                Name = item.Name,
                                                                IsActive = item.IsActive,
                                                                Description = item.Description
                                                            };

Is there any other way vs. adding AsQuerable() to thousands of queries?

@nafberger
Copy link

nafberger commented Apr 8, 2021

I can maybe suggest the answer cited here, it helped me with a similar problem

googleapis/google-cloud-dotnet#6315

@roji
Copy link
Member

roji commented Apr 8, 2021

@nafberger and others, note that this problem has been fixed for EF Core 6.0 (#24041), the latest previous should already not trigger the ambiguity.

@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

6 participants