Skip to content

Commit 44347c0

Browse files
committed
NH-3190 - Port-back fix
HqlGeneratorExpressionTreeVisitor should not convert boolean equality operator to case operator when node is a sub-query with single or first result operators
1 parent c885cce commit 44347c0

File tree

2 files changed

+69
-0
lines changed

2 files changed

+69
-0
lines changed

src/NHibernate.Test/Linq/WhereSubqueryTests.cs

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -547,5 +547,61 @@ public void SubqueryWhereFailingTest3()
547547

548548
Assert.That(list.Count, Is.EqualTo(2155));
549549
}
550+
551+
[Test]
552+
public void ProductsWithSubqueryReturningBoolFirstOrDefaultEq()
553+
{
554+
//NH-3190
555+
var result = (from p in db.Products
556+
where (from c in db.Categories
557+
where c.Name == "Confections"
558+
&& c == p.Category
559+
select p.Discontinued).FirstOrDefault() == false
560+
select p)
561+
.ToList();
562+
563+
Assert.That(result.Count, Is.EqualTo(13));
564+
}
565+
566+
[Test]
567+
public void CategoriesWithFirstProductIsNotDiscouned()
568+
{
569+
//NH-3190
570+
var result = (from c in db.Categories
571+
where c.Products.Select(p => p.Discontinued).FirstOrDefault() == false
572+
select c).ToList();
573+
574+
Assert.That(result.Count, Is.EqualTo(7));
575+
}
576+
577+
[Test, Ignore("Not fixed yet.")]
578+
public void ProductsWithSubqueryReturningProjectionBoolFirstOrDefaultEq()
579+
{
580+
//NH-3190
581+
var result = (from p in db.Products
582+
where (from c in db.Categories
583+
where c.Name == "Confections"
584+
&& c == p.Category
585+
select new{R=p.Discontinued}).FirstOrDefault().R == false
586+
select p)
587+
.ToList();
588+
589+
Assert.That(result.Count, Is.EqualTo(13));
590+
}
591+
592+
[Test]
593+
public void ProductsWithSubqueryReturningStringFirstOrDefaultEq()
594+
{
595+
//NH-3190
596+
var result = (from p in db.Products
597+
where (from c in db.Categories
598+
where c.Name == "Confections"
599+
&& c == p.Category
600+
select p.Name).FirstOrDefault() == p.Name
601+
select p)
602+
.ToList();
603+
604+
Assert.That(result.Count, Is.EqualTo(13));
605+
}
550606
}
551607
}

src/NHibernate/Linq/Visitors/HqlGeneratorExpressionTreeVisitor.cs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
using NHibernate.Linq.Functions;
88
using NHibernate.Param;
99
using Remotion.Linq.Clauses.Expressions;
10+
using Remotion.Linq.Clauses.ResultOperators;
1011

1112
namespace NHibernate.Linq.Visitors
1213
{
@@ -327,6 +328,18 @@ private HqlExpression GetExpressionForBooleanEquality(Expression @operator, HqlE
327328
return original;
328329
}
329330

331+
var subQueryExpression = @operator as SubQueryExpression;
332+
if (subQueryExpression != null)
333+
{
334+
var resultOperators = subQueryExpression.QueryModel.ResultOperators;
335+
if (resultOperators.Count == 1 &&
336+
(resultOperators[0] is FirstResultOperator ||
337+
resultOperators[0] is SingleResultOperator))
338+
{
339+
return original;
340+
}
341+
}
342+
330343
//When the expression is a member-access nullable then use the "case" clause to transform it to boolean (to use always .NET meaning instead leave the DB the behavior for null)
331344
//When the expression is a complex-expression then use the "case" clause to transform it to boolean
332345
return _hqlTreeBuilder.Case(new[] {_hqlTreeBuilder.When(original, _hqlTreeBuilder.True())}, _hqlTreeBuilder.False());

0 commit comments

Comments
 (0)