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

HashSet parameter in query not recognized by EF #18198

Closed
Eirenarch opened this issue Oct 3, 2019 · 1 comment
Closed

HashSet parameter in query not recognized by EF #18198

Eirenarch opened this issue Oct 3, 2019 · 1 comment

Comments

@Eirenarch
Copy link

Eirenarch commented Oct 3, 2019

In previous versions of EF one could use a HashSet in the query with Contains. With EFCore 3.0 it doesn't work anymore

Steps to reproduce

    public class TestContext : DbContext
    {
        public DbSet<Item> Items { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder options)
        {
            options.UseSqlServer("Data Source=.\\SQLEXPRESS;Initial Catalog=TestDB;Integrated Security=True");
        }
    }

    public class Item
    {
        public int ItemId { get; set; }
    }

    class Program
    {
        public static async Task Main()
        {
            using var context = new TestContext();

            HashSet<int> ids = new HashSet<int> { 1 }; //doesn't work
            //IEnumerable<int> ids = new HashSet<int> { 1 }; //works

            List<Item> items = await (from item in context.Items
                                      where ids.Contains(item.ItemId)
                                      select item).ToListAsync();
        }
    }

When the static type of the variable is IEnumerable the LINQ extension method is used and the method works as expected. When the static type is HashSet EF doesn't recognize the HashSet.Contains instance method and I get an exception. Note that this same code works fine with EF Code 2.2. I believe this case should be supported because 1) it is a regression, 2) it is annoying to have to change the static type of the variable to make EF happy, 3) the issue is only reported at runtime and with an error message that incorrectly points to client evaluation, 4) the pattern is fairly common - gather a bunch of ids that should be included or excluded from the result but do so in set because the way you collect them includes duplicates

System.InvalidOperationException
HResult=0x80131509
Message=The LINQ expression 'Where(
source: DbSet,
predicate: (i) => (Unhandled parameter: __ids_0).Contains(i.ItemId))' could not be translated. Either rewrite the query in a form that can be translated, or switch to client evaluation explicitly by inserting a call to either AsEnumerable(), AsAsyncEnumerable(), ToList(), or ToListAsync(). See https://go.microsoft.com/fwlink/?linkid=2101038 for more information.
Source=Microsoft.EntityFrameworkCore
StackTrace:
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.g__CheckTranslated|8_0(ShapedQueryExpression translated, <>c__DisplayClass8_0& )
at Microsoft.EntityFrameworkCore.Query.QueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at Microsoft.EntityFrameworkCore.Query.RelationalQueryableMethodTranslatingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass12_01.<ExecuteAsync>b__0() at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func1 compiler)
at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func1 compiler) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.ExecuteAsync[TResult](Expression expression, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable1.GetAsyncEnumerator(CancellationToken cancellationToken)
at System.Runtime.CompilerServices.ConfiguredCancelableAsyncEnumerable1.GetAsyncEnumerator() at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.<ToListAsync>d__641.MoveNext()
at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task)
at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
at EFCoreBugs.Program.

d__0.MoveNext() in

Further technical details

EF Core version: 3.0
Database provider: Microsoft.EntityFrameworkCore.SqlServer (maybe others)
Target framework: .NET Core 3.0

@smitpatel
Copy link
Contributor

Duplicate of #17877

@smitpatel smitpatel marked this as a duplicate of #17877 Oct 3, 2019
@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

3 participants