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

InvalidCastException when merging expressions in projection #19380

Closed
bpaczkowski opened this issue Dec 22, 2019 · 2 comments
Closed

InvalidCastException when merging expressions in projection #19380

bpaczkowski opened this issue Dec 22, 2019 · 2 comments

Comments

@bpaczkowski
Copy link

bpaczkowski commented Dec 22, 2019

When merging multiple expressions with Expression.AndAlso, that merge cannot be performed directly in the projection. I have to first assign it to a variable before and use that variable instead.

Steps to reproduce

Overview of the repro:

[TestMethod]
public void Passing()
{
	using DatabaseContext databaseContext = new DatabaseContext();

	Expression<Func<ModelB, bool>> expr = GetModelExpression().AndAlso(m => m.Value == 1);

	var projection = databaseContext.ModelAs.Select(
			model => new
			{
				modelA = model,
				modelB = model.ModelBs.AsQueryable().FirstOrDefault(expr)
			})
		.FirstOrDefault();

	Assert.IsNull(projection);
}

[TestMethod]
public void Failing()
{
	using DatabaseContext databaseContext = new DatabaseContext();

	var projection = databaseContext.ModelAs.Select(
			model => new
			{
				modelA = model,
				modelB = model.ModelBs.AsQueryable().FirstOrDefault(GetModelExpression().AndAlso(m => m.Value == 1))
			})
		.FirstOrDefault();

	Assert.IsNull(projection);
}

private static Expression<Func<ModelB, bool>> GetModelExpression()
{
	return model => model.Name == "fooBar";
}

Exception:

Repro.UnitTest.Failing

Test method Repro.UnitTest.Failing threw exception: 
System.InvalidCastException: Unable to cast object of type 'System.Linq.Expressions.MethodCallExpression2' to type 'System.Linq.Expressions.LambdaExpression'.
    at System.Linq.Expressions.ExpressionExtensions.UnwrapLambdaFromQuote(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.VisitMethodCall(MethodCallExpression methodCallExpression)
   at System.Linq.Expressions.MethodCallExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Dynamic.Utils.ExpressionVisitorUtils.VisitArguments(ExpressionVisitor visitor, IArgumentProvider nodes)
   at System.Linq.Expressions.ExpressionVisitor.VisitNew(NewExpression node)
   at System.Linq.Expressions.NewExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.PendingSelectorExpandingExpressionVisitor.Visit(Expression expression)
   at Microsoft.EntityFrameworkCore.Query.Internal.NavigationExpandingExpressionVisitor.Expand(Expression query)
   at Microsoft.EntityFrameworkCore.Query.QueryTranslationPreprocessor.Process(Expression query)
   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__DisplayClass9_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
   at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source)
   at Repro.UnitTest.Failing() in C:\dev\efcore_expression_exception\Repro\UnitTest.cs:line 34

Here is the repro solution: efcore_expression_exception.zip

Further technical details

EF Core version: 3.1.0
Database provider: Microsoft.EntityFrameworkCore.InMemory
Target framework: .NET Core 3.1
Operating system: Windows 10
IDE: JetBrains Rider

@ajcvickers
Copy link
Member

Possible dupes: #16104 #10497

@ajcvickers
Copy link
Member

Note from team discussion: We will document how to correctly compose as part of dotnet/EntityFramework.Docs#1956

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

2 participants