From a8ceb18006de63f7b2a1ed2229bbf5880f940644 Mon Sep 17 00:00:00 2001 From: Svyatoslav Danyliv Date: Thu, 7 Apr 2022 13:27:01 +0300 Subject: [PATCH] Fixed unexpected extension evaluation. --- .../LinqToDBForEFToolsImplDefault.cs | 30 ++++++++++++++----- 1 file changed, 23 insertions(+), 7 deletions(-) diff --git a/Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFToolsImplDefault.cs b/Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFToolsImplDefault.cs index 29c7d7c..b88b5ac 100644 --- a/Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFToolsImplDefault.cs +++ b/Source/LinqToDB.EntityFrameworkCore/LinqToDBForEFToolsImplDefault.cs @@ -767,12 +767,24 @@ public virtual Expression TransformExpression(Expression expression, IDataContex var tracking = true; var ignoreTracking = false; + var nonEvaluatableParameters = new HashSet(); + TransformInfo LocalTransform(Expression e) { e = CompactExpression(e); switch (e.NodeType) { + case ExpressionType.Lambda: + { + foreach (var parameter in ((LambdaExpression)e).Parameters) + { + nonEvaluatableParameters.Add(parameter); + } + + break; + } + case ExpressionType.Constant: { if (dc != null && typeof(EntityQueryable<>).IsSameOrParentOf(e.Type) || typeof(DbSet<>).IsSameOrParentOf(e.Type)) @@ -905,14 +917,18 @@ TransformInfo LocalTransform(Expression e) if (typeof(IQueryable<>).IsSameOrParentOf(methodCall.Type)) { - // Invoking function to evaluate EF's Subquery located in function - - var obj = EvaluateExpression(methodCall.Object); - var arguments = methodCall.Arguments.Select(EvaluateExpression).ToArray(); - if (methodCall.Method.Invoke(obj, arguments) is IQueryable result) + if (null == methodCall.Find(nonEvaluatableParameters, + (c, t) => t.NodeType == ExpressionType.Parameter && c.Contains(t))) { - if (!ExpressionEqualityComparer.Instance.Equals(methodCall, result.Expression)) - return new TransformInfo(result.Expression, false, true); + // Invoking function to evaluate EF's Subquery located in function + + var obj = EvaluateExpression(methodCall.Object); + var arguments = methodCall.Arguments.Select(EvaluateExpression).ToArray(); + if (methodCall.Method.Invoke(obj, arguments) is IQueryable result) + { + if (!ExpressionEqualityComparer.Instance.Equals(methodCall, result.Expression)) + return new TransformInfo(result.Expression, false, true); + } } }