Skip to content

Commit 7740493

Browse files
committed
NH-3474 - Fix ExpressionKeyVisitor handling of constant IEnumerables to show initialization values
1 parent fbe1ddc commit 7740493

File tree

2 files changed

+49
-15
lines changed

2 files changed

+49
-15
lines changed

src/NHibernate.Test/Linq/ByMethod/GroupByTests.cs

Lines changed: 25 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -595,22 +595,33 @@ public void GroupByKeyWithConstantFromVariable()
595595
{
596596
constKey = 1;
597597
var q1 = db.Orders.GroupBy(o => constKey).Select(g => new {Key = g.Key, Count = g.Count(), Sum = g.Sum(x => x.Freight)});
598+
var q1a = db.Orders.GroupBy(o => "").Select(g => new {Key = g.Key, Count = g.Count(), Sum = g.Sum(x => x.Freight)});
598599
var q2 = db.Orders.GroupBy(o => new {A = constKey}).Select(g => new {Key = g.Key, Count = g.Count(), Sum = g.Sum(x => x.Freight)});
599600
var q3 = db.Orders.GroupBy(o => new object[] {constKey}).Select(g => new {Key = g.Key, Count = g.Count(), Sum = g.Sum(x => x.Freight)});
601+
var q3a = db.Orders.GroupBy(o => (IEnumerable<object>) new object[] {constKey}).Select(g => new {Key = g.Key, Count = g.Count(), Sum = g.Sum(x => x.Freight)});
600602
var q4 = db.Orders.GroupBy(o => new {A = constKey, B = o.Shipper.ShipperId}).Select(g => new {Key = g.Key, Count = g.Count(), Sum = g.Sum(x => x.Freight)});
601603
var q5 = db.Orders.GroupBy(o => new[] {constKey, o.Shipper.ShipperId}).Select(g => new {Key = g.Key, Count = g.Count(), Sum = g.Sum(x => x.Freight)});
604+
var q5a = db.Orders.GroupBy(o => (IEnumerable<int>) new[] {constKey, o.Shipper.ShipperId}).Select(g => new {Key = g.Key, Count = g.Count(), Sum = g.Sum(x => x.Freight)});
602605

603606
var r1_1 = q1.ToList();
604607
Assert.That(r1_1.Count, Is.EqualTo(1));
605608
Assert.That(r1_1, Has.All.With.Property("Key").EqualTo(1));
606609

610+
var r1a_1 = q1a.ToList();
611+
Assert.That(r1a_1.Count, Is.EqualTo(1));
612+
Assert.That(r1a_1, Has.All.With.Property("Key").EqualTo(""));
613+
607614
var r2_1 = q2.ToList();
608615
Assert.That(r2_1.Count, Is.EqualTo(1));
609616
Assert.That(r2_1, Has.All.With.Property("Key").With.Property("A").EqualTo(1));
610617

611618
var r3_1 = q3.ToList();
612619
Assert.That(r3_1.Count, Is.EqualTo(1));
613-
Assert.That(r3_1, Has.All.With.Property("Key").EqualTo(new object[] { 1 }));
620+
Assert.That(r3_1, Has.All.With.Property("Key").EquivalentTo(new object[] { 1 }));
621+
622+
var r3a_1 = q3a.ToList();
623+
Assert.That(r3a_1.Count, Is.EqualTo(1));
624+
Assert.That(r3a_1, Has.All.With.Property("Key").EquivalentTo(new object[] { 1 }));
614625

615626
var r4_1 = q4.ToList();
616627
Assert.That(r4_1.Count, Is.EqualTo(3));
@@ -620,6 +631,10 @@ public void GroupByKeyWithConstantFromVariable()
620631
Assert.That(r5_1.Count, Is.EqualTo(3));
621632
Assert.That(r5_1, Has.All.With.Property("Key").Contains(1));
622633

634+
var r6_1 = q5a.ToList();
635+
Assert.That(r6_1.Count, Is.EqualTo(3));
636+
Assert.That(r6_1, Has.All.With.Property("Key").Contains(1));
637+
623638
constKey = 2;
624639

625640
var r1_2 = q1.ToList();
@@ -632,7 +647,11 @@ public void GroupByKeyWithConstantFromVariable()
632647

633648
var r3_2 = q3.ToList();
634649
Assert.That(r3_2.Count, Is.EqualTo(1));
635-
Assert.That(r3_2, Has.All.With.Property("Key").EqualTo(new object[] { constKey }));
650+
Assert.That(r3_2, Has.All.With.Property("Key").EquivalentTo(new object[] { 2 }));
651+
652+
var r3a_2 = q3a.ToList();
653+
Assert.That(r3a_2.Count, Is.EqualTo(1));
654+
Assert.That(r3a_2, Has.All.With.Property("Key").EquivalentTo(new object[] { 2 }));
636655

637656
var r4_2 = q4.ToList();
638657
Assert.That(r4_2.Count, Is.EqualTo(3));
@@ -641,6 +660,10 @@ public void GroupByKeyWithConstantFromVariable()
641660
var r5_2 = q5.ToList();
642661
Assert.That(r5_2.Count, Is.EqualTo(3));
643662
Assert.That(r5_2, Has.All.With.Property("Key").Contains(2));
663+
664+
var r6_2 = q5.ToList();
665+
Assert.That(r6_2.Count, Is.EqualTo(3));
666+
Assert.That(r6_2, Has.All.With.Property("Key").Contains(2));
644667
}
645668

646669
[Test(Description = "NH-3801")]

src/NHibernate/Linq/Visitors/ExpressionKeyVisitor.cs

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -84,30 +84,41 @@ protected override Expression VisitConstantExpression(ConstantExpression express
8484
{
8585
// Nulls generate different query plans. X = variable generates a different query depending on if variable is null or not.
8686
if (param.Value == null)
87+
{
8788
_string.Append("NULL");
88-
if (param.Value is IEnumerable && !((IEnumerable)param.Value).Cast<object>().Any())
89-
_string.Append("EmptyList");
89+
}
9090
else
91-
_string.Append(param.Name);
91+
{
92+
var value = param.Value as IEnumerable;
93+
if (value != null && !(value is string) && !value.Cast<object>().Any())
94+
{
95+
_string.Append("EmptyList");
96+
}
97+
else
98+
{
99+
_string.Append(param.Name);
100+
}
101+
}
92102
}
93103
else
94104
{
95105
if (expression.Value == null)
96106
{
97107
_string.Append("NULL");
98108
}
99-
else if (expression.Type.IsArray)
100-
{
101-
// Const arrays all look the same (they just display the type of array and not the initializer contents
102-
// Since the contents might be different, we need to include those as well so we don't use a cached query plan by mistake
103-
_string.Append(expression.Value);
104-
_string.Append(" {");
105-
_string.Append(String.Join(",", (object[]) expression.Value));
106-
_string.Append("}");
107-
}
108109
else
109110
{
110-
_string.Append(expression.Value);
111+
var value = expression.Value as IEnumerable;
112+
if (value != null && !(value is string) && !(value is IQueryable))
113+
{
114+
_string.Append("{");
115+
_string.Append(String.Join(",", value.Cast<object>()));
116+
_string.Append("}");
117+
}
118+
else
119+
{
120+
_string.Append(expression.Value);
121+
}
111122
}
112123
}
113124

0 commit comments

Comments
 (0)