From 5402e378e51e7d8ccbcc1cf070b9d4a74a79d21a Mon Sep 17 00:00:00 2001 From: maca88 Date: Tue, 15 Sep 2020 17:55:00 +0200 Subject: [PATCH 1/2] Fix parameter detection for expression arguments --- .../Async/Linq/WhereSubqueryTests.cs | 25 +++++++++++++++++++ .../Linq/WhereSubqueryTests.cs | 25 +++++++++++++++++++ .../NhPartialEvaluatingExpressionVisitor.cs | 4 ++- 3 files changed, 53 insertions(+), 1 deletion(-) diff --git a/src/NHibernate.Test/Async/Linq/WhereSubqueryTests.cs b/src/NHibernate.Test/Async/Linq/WhereSubqueryTests.cs index 713b931e3b7..38303f0986d 100644 --- a/src/NHibernate.Test/Async/Linq/WhereSubqueryTests.cs +++ b/src/NHibernate.Test/Async/Linq/WhereSubqueryTests.cs @@ -707,5 +707,30 @@ public async Task NullComparedToMemberInitExpressionInWhereClauseAsync() Assert.That(result.Count, Is.EqualTo(45)); } + + public class Specification + { + private Expression> _expression; + + public Specification(Expression> expression) + { + _expression = expression; + } + + public static implicit operator Expression>(Specification specification) + { + return specification._expression; + } + } + + [Test] + public async Task ImplicitConversionInsideWhereSubqueryExpressionAsync() + { + if (!Dialect.SupportsScalarSubSelects) + Assert.Ignore(Dialect.GetType().Name + " does not support scalar sub-queries"); + + var spec = new Specification(x => x.Freight > 1000); + await (db.Orders.Where(o => db.Orders.Where(spec).Any(x => x.OrderId == o.OrderId)).ToListAsync()); + } } } diff --git a/src/NHibernate.Test/Linq/WhereSubqueryTests.cs b/src/NHibernate.Test/Linq/WhereSubqueryTests.cs index 99437428623..9531ccf7273 100644 --- a/src/NHibernate.Test/Linq/WhereSubqueryTests.cs +++ b/src/NHibernate.Test/Linq/WhereSubqueryTests.cs @@ -788,5 +788,30 @@ public void NullComparedToMemberInitExpressionInWhereClause() Assert.That(result.Count, Is.EqualTo(45)); } + + public class Specification + { + private Expression> _expression; + + public Specification(Expression> expression) + { + _expression = expression; + } + + public static implicit operator Expression>(Specification specification) + { + return specification._expression; + } + } + + [Test] + public void ImplicitConversionInsideWhereSubqueryExpression() + { + if (!Dialect.SupportsScalarSubSelects) + Assert.Ignore(Dialect.GetType().Name + " does not support scalar sub-queries"); + + var spec = new Specification(x => x.Freight > 1000); + db.Orders.Where(o => db.Orders.Where(spec).Any(x => x.OrderId == o.OrderId)).ToList(); + } } } diff --git a/src/NHibernate/Linq/Visitors/NhPartialEvaluatingExpressionVisitor.cs b/src/NHibernate/Linq/Visitors/NhPartialEvaluatingExpressionVisitor.cs index 475dbcdad31..c59bfb8a1da 100644 --- a/src/NHibernate/Linq/Visitors/NhPartialEvaluatingExpressionVisitor.cs +++ b/src/NHibernate/Linq/Visitors/NhPartialEvaluatingExpressionVisitor.cs @@ -157,7 +157,9 @@ private Expression EvaluateSubtree(Expression subtree) private bool ContainsVariable(Expression expression) { - if (!(expression is UnaryExpression unaryExpression)) + if (!(expression is UnaryExpression unaryExpression) || + // Avoid detecting expression variables as parameters + typeof(Expression).IsAssignableFrom(expression.Type.UnwrapIfNullable())) { return false; } From 6501e4ee935f85c5b90e463a1e9620bae51e80ba Mon Sep 17 00:00:00 2001 From: maca88 Date: Wed, 16 Sep 2020 19:55:54 +0200 Subject: [PATCH 2/2] Remove unnecessary type unwrap --- .../Linq/Visitors/NhPartialEvaluatingExpressionVisitor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/NHibernate/Linq/Visitors/NhPartialEvaluatingExpressionVisitor.cs b/src/NHibernate/Linq/Visitors/NhPartialEvaluatingExpressionVisitor.cs index c59bfb8a1da..c92403cbc82 100644 --- a/src/NHibernate/Linq/Visitors/NhPartialEvaluatingExpressionVisitor.cs +++ b/src/NHibernate/Linq/Visitors/NhPartialEvaluatingExpressionVisitor.cs @@ -159,7 +159,7 @@ private bool ContainsVariable(Expression expression) { if (!(expression is UnaryExpression unaryExpression) || // Avoid detecting expression variables as parameters - typeof(Expression).IsAssignableFrom(expression.Type.UnwrapIfNullable())) + typeof(Expression).IsAssignableFrom(expression.Type)) { return false; }