efcore: 2.0.1-rtm-203 regression: System.InvalidCastException: Unable to cast object of type 'System.Int32' to type 'System.Linq.Expressions.LambdaExpression'

When configuring a query filter that captures a variable (I think that’s whats it called?) in the expression 2.0.1-rtm-203 throws an InvalidCastException. This doesn’t happen in 2.0.0

// Works
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<MyEntity>().HasQueryFilter(e => e.TenantId == 123);
}

// Throws InvalidCastException when executing a query.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    int tenantId = 123;
    modelBuilder.Entity<MyEntity>().HasQueryFilter(e => e.TenantId == tenantId);
}

OR

  1. git clone https://github.com/nphmuller/EfCoreQueryFilterBug
  2. dotnet run throws exception. (See below for details)
  3. open .csproj file and change version from 2.0.1-* to 2.0.0
  4. dotnet run completes succesfully.

Same thing occurs when I use: https://dotnet.myget.org/gallery/aspnet-2-0-2-october2017-patch - 2.0.1-rtm-207 instead of: https://dotnet.myget.org/gallery/aspnet-2-0-2-october2017-patch-public - 2.0.1-rtm-203

Exception details:

Unhandled Exception: System.AggregateException: One or more errors occurred. (Unable to cast object of type 'System.Int32' to type 'System.Linq.Expressions.LambdaExpression'.) ---> System.InvalidCastException: Unable to cast object of type 'System.Int32' to type 'System.Linq.Expressions.LambdaExpression'.
   at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.CreateSetFilterParametersExpressions(ParameterExpression& contextVariableExpression)
   at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.CreateExecutorLambda[TResults]()
   at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.CreateQueryExecutor[TResult](QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Storage.Internal.InMemoryDatabase.CompileAsyncQuery[TResult](QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass24_0`1.<CompileAsyncQuery>b__0()
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.System.Collections.Generic.IAsyncEnumerable<TResult>.GetEnumerator()
   at System.Linq.AsyncEnumerable.<Aggregate_>d__6`3.MoveNext()
   --- End of inner exception stack trace ---
   at System.Threading.Tasks.Task`1.GetResultCore(Boolean waitCompletionNotification)
   at ConsoleApp3.Program.Main(String[] args) in C:\Dev\_EfCoreQueryFilterBug\ConsoleApp3\Program.cs:line 14

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Comments: 23 (11 by maintainers)

Commits related to this issue

Most upvoted comments

I can confirm that it does work as I expect it to work in 2.0.0. To test, I have three “admin” users. One doesn’t have a tenant id, which makes them a system user, the other two have different tenant ids which makes them users for two different tenants.

I logged in and out of each one in order, 10 times each, for a total of 30 sessions. When logging into the system user I was redirected to the system dashboard page. When logging in as the tenant users I was redirected to the tenant dashboard page where the user’s tenant company name was written out. Everything worked as it should have.

So, correct me if I’m wrong, but the official stance on this issue for 2.0.1+ is that query filters that depend on outside values have to be defined in the OnModelCreating method. The reason being is that although the DbContext is instanced per scope, the EntityTypeConfiguration classes are instanced once, probably at start of application or first call into the DbContext, and their results are cached for the duration of the app’s lifetime and thus the query filter values are permanently inlined. Do I have it right?

@nphmuller - No need to apologize. It is indeed bug. Thanks for reporting it to us. I am just try to collect data on use-case so that we can determine, how critical it is and should be fixed in next patch or not.

Ah, seems I misremembered then. Sorry!

Initially I was trying to split the filter logic from my dbcontext, but since it’s not possible to change the filter value that way, I’ve settled for setting the value at dbcontext level.