Skip to content

Commit e9f43d6

Browse files
authored
Add Projections.Conditional for CASE expressions with multiple conditions (#2816)
Fixes #2804
1 parent f4df9a1 commit e9f43d6

File tree

5 files changed

+402
-86
lines changed

5 files changed

+402
-86
lines changed
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
//------------------------------------------------------------------------------
2+
// <auto-generated>
3+
// This code was generated by AsyncGenerator.
4+
//
5+
// Changes to this file may cause incorrect behavior and will be lost if
6+
// the code is regenerated.
7+
// </auto-generated>
8+
//------------------------------------------------------------------------------
9+
10+
11+
using System;
12+
using System.Linq;
13+
using NHibernate.Criterion;
14+
using NUnit.Framework;
15+
16+
namespace NHibernate.Test.Criteria
17+
{
18+
using System.Threading.Tasks;
19+
[TestFixture]
20+
public class ConditionalProjectionTestAsync : TestCase
21+
{
22+
protected override string MappingsAssembly => "NHibernate.Test";
23+
24+
protected override string[] Mappings => new [] {"Criteria.Enrolment.hbm.xml"};
25+
26+
protected override void OnSetUp()
27+
{
28+
using (var session = OpenSession())
29+
using (var transaction = session.BeginTransaction())
30+
{
31+
session.Save(new Student {StudentNumber = 6L, Name = "testa"});
32+
session.Save(new Student {StudentNumber = 5L, Name = "testz"});
33+
session.Save(new Student {StudentNumber = 4L, Name = "test1"});
34+
session.Save(new Student {StudentNumber = 3L, Name = "test2"});
35+
session.Save(new Student {StudentNumber = 2L, Name = "test998"});
36+
session.Save(new Student {StudentNumber = 1L, Name = "test999"});
37+
transaction.Commit();
38+
}
39+
}
40+
41+
protected override void OnTearDown()
42+
{
43+
using (var session = Sfi.OpenSession())
44+
using (var transaction = session.BeginTransaction())
45+
{
46+
session.CreateQuery("delete from System.Object").ExecuteUpdate();
47+
transaction.Commit();
48+
}
49+
}
50+
51+
protected override bool AppliesTo(Dialect.Dialect dialect)
52+
{
53+
return !TestDialect.HasBrokenTypeInferenceOnSelectedParameters;
54+
}
55+
56+
[Test]
57+
public async Task UsingMultiConditionalsAsync()
58+
{
59+
using (var session = OpenSession())
60+
using (session.BeginTransaction())
61+
{
62+
// when Name = "testa" then 1 ...
63+
var orderOfNames = new Tuple<string, string>[]
64+
{
65+
System.Tuple.Create("test1", "1"),
66+
System.Tuple.Create("testz", "2"),
67+
System.Tuple.Create("test2", "3"),
68+
System.Tuple.Create("testa", "4")
69+
};
70+
71+
var criterionProjections =
72+
orderOfNames
73+
.Select(
74+
x => new ConditionalProjectionCase(
75+
Restrictions.Eq(nameof(Student.Name), x.Item1),
76+
Projections.Constant(x.Item2)))
77+
.ToArray();
78+
79+
// ... else 99
80+
var elseProjection = Projections.Constant("99");
81+
82+
var conditionalsProjection = Projections.Conditional(criterionProjections, elseProjection);
83+
84+
var order = Order.Asc(conditionalsProjection);
85+
86+
var criteria = session.CreateCriteria(typeof(Student)).AddOrder(order);
87+
88+
var actuals = await (criteria.ListAsync<Student>());
89+
90+
Assert.That(actuals.Count, Is.GreaterThanOrEqualTo(orderOfNames.Length));
91+
for (var i = 0; i < orderOfNames.Length; i++)
92+
{
93+
var expected = orderOfNames[i];
94+
var actual = actuals[i];
95+
96+
Assert.That(actual.Name, Is.EqualTo(expected.Item1));
97+
}
98+
}
99+
}
100+
}
101+
}
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
using System;
2+
using System.Linq;
3+
using NHibernate.Criterion;
4+
using NUnit.Framework;
5+
6+
namespace NHibernate.Test.Criteria
7+
{
8+
[TestFixture]
9+
public class ConditionalProjectionTest : TestCase
10+
{
11+
protected override string MappingsAssembly => "NHibernate.Test";
12+
13+
protected override string[] Mappings => new [] {"Criteria.Enrolment.hbm.xml"};
14+
15+
protected override void OnSetUp()
16+
{
17+
using (var session = OpenSession())
18+
using (var transaction = session.BeginTransaction())
19+
{
20+
session.Save(new Student {StudentNumber = 6L, Name = "testa"});
21+
session.Save(new Student {StudentNumber = 5L, Name = "testz"});
22+
session.Save(new Student {StudentNumber = 4L, Name = "test1"});
23+
session.Save(new Student {StudentNumber = 3L, Name = "test2"});
24+
session.Save(new Student {StudentNumber = 2L, Name = "test998"});
25+
session.Save(new Student {StudentNumber = 1L, Name = "test999"});
26+
transaction.Commit();
27+
}
28+
}
29+
30+
protected override void OnTearDown()
31+
{
32+
using (var session = Sfi.OpenSession())
33+
using (var transaction = session.BeginTransaction())
34+
{
35+
session.CreateQuery("delete from System.Object").ExecuteUpdate();
36+
transaction.Commit();
37+
}
38+
}
39+
40+
protected override bool AppliesTo(Dialect.Dialect dialect)
41+
{
42+
return !TestDialect.HasBrokenTypeInferenceOnSelectedParameters;
43+
}
44+
45+
[Test]
46+
public void UsingMultiConditionals()
47+
{
48+
using (var session = OpenSession())
49+
using (session.BeginTransaction())
50+
{
51+
// when Name = "testa" then 1 ...
52+
var orderOfNames = new Tuple<string, string>[]
53+
{
54+
System.Tuple.Create("test1", "1"),
55+
System.Tuple.Create("testz", "2"),
56+
System.Tuple.Create("test2", "3"),
57+
System.Tuple.Create("testa", "4")
58+
};
59+
60+
var criterionProjections =
61+
orderOfNames
62+
.Select(
63+
x => new ConditionalProjectionCase(
64+
Restrictions.Eq(nameof(Student.Name), x.Item1),
65+
Projections.Constant(x.Item2)))
66+
.ToArray();
67+
68+
// ... else 99
69+
var elseProjection = Projections.Constant("99");
70+
71+
var conditionalsProjection = Projections.Conditional(criterionProjections, elseProjection);
72+
73+
var order = Order.Asc(conditionalsProjection);
74+
75+
var criteria = session.CreateCriteria(typeof(Student)).AddOrder(order);
76+
77+
var actuals = criteria.List<Student>();
78+
79+
Assert.That(actuals.Count, Is.GreaterThanOrEqualTo(orderOfNames.Length));
80+
for (var i = 0; i < orderOfNames.Length; i++)
81+
{
82+
var expected = orderOfNames[i];
83+
var actual = actuals[i];
84+
85+
Assert.That(actual.Name, Is.EqualTo(expected.Item1));
86+
}
87+
}
88+
}
89+
}
90+
}

0 commit comments

Comments
 (0)