Skip to content

Commit 4d8821b

Browse files
committed
GH-1879 - Nested conditional subquery expansion tests and logic
1 parent aaa0b60 commit 4d8821b

File tree

7 files changed

+339
-10
lines changed

7 files changed

+339
-10
lines changed

src/NHibernate.Test/Async/NHSpecificTest/GH1879/FixtureByCode.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ protected override HbmMapping GetMappings()
4444
rc.ManyToOne(x => x.Client, m => m.Column("ClientId"));
4545
rc.ManyToOne(x => x.BillingClient, m => m.Column("BillingClientId"));
4646
rc.ManyToOne(x => x.CorporateClient, m => m.Column("CorporateClientId"));
47+
rc.Set(x => x.Issues,
48+
m =>
49+
{
50+
m.Key(k => k.Column(c => c.Name("ProjectId")) );
51+
},
52+
rel => rel.OneToMany());
4753
});
4854
mapper.Class<Issue>(rc =>
4955
{
@@ -64,6 +70,14 @@ protected override HbmMapping GetMappings()
6470
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
6571
rc.Property(x => x.Name);
6672
rc.Property(x => x.ReviewAsPrimary);
73+
rc.Set(x => x.Projects,
74+
m =>
75+
{
76+
m.Table("EmployeesToProjects");
77+
m.Cascade(Mapping.ByCode.Cascade.All | Mapping.ByCode.Cascade.DeleteOrphans);
78+
m.Key(k => k.Column(c => c.Name("EmployeeId")) );
79+
},
80+
rel => rel.ManyToMany(m => m.Column("ProjectId")));
6781
rc.Set(x => x.WorkIssues,
6882
m =>
6983
{
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
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.Linq;
12+
using NUnit.Framework;
13+
14+
namespace NHibernate.Test.NHSpecificTest.GH1879
15+
{
16+
using System.Threading.Tasks;
17+
[TestFixture]
18+
public class NestedConditionalThenMethodCallAsync : GH1879BaseFixtureAsync<Employee>
19+
{
20+
/// <inheritdoc />
21+
protected override void OnSetUp()
22+
{
23+
using (var session = OpenSession())
24+
using (var transaction = session.BeginTransaction())
25+
{
26+
var clientA = new Client { Name = "Alpha" };
27+
var clientB = new Client { Name = "Beta" };
28+
session.Save(clientA);
29+
session.Save(clientB);
30+
31+
var projectA = new Project { Name = "Apple" };
32+
var projectB = new Project { Name = "Banana" };
33+
var projectC = new Project { Name = "Cherry" };
34+
session.Save(projectA);
35+
session.Save(projectB);
36+
session.Save(projectC);
37+
38+
var issue1 = new Issue { Name = "1", Client = null, Project = null };
39+
var issue2 = new Issue { Name = "2", Client = clientA, Project = projectA };
40+
var issue3 = new Issue { Name = "3", Client = clientA, Project = projectA };
41+
var issue4 = new Issue { Name = "4", Client = clientA, Project = projectB };
42+
var issue5 = new Issue { Name = "5", Client = clientB, Project = projectC };
43+
session.Save(issue1);
44+
session.Save(issue2);
45+
session.Save(issue3);
46+
session.Save(issue4);
47+
session.Save(issue5);
48+
49+
session.Save(new Employee { Name = "Andy", ReviewAsPrimary = true, ReviewIssues = { issue1, issue2, issue5 }, WorkIssues = { issue3 }, Projects = { projectA, projectB } });
50+
session.Save(new Employee { Name = "Bart", ReviewAsPrimary = false, ReviewIssues = { issue3 }, WorkIssues = { issue4, issue5 }, Projects = { projectB, projectC } });
51+
session.Save(new Employee { Name = "Carl", ReviewAsPrimary = true, ReviewIssues = { issue3 }, WorkIssues = { issue1, issue4, issue5 }, Projects = { projectC } });
52+
session.Save(new Employee { Name = "Dorn", ReviewAsPrimary = false, ReviewIssues = { issue3 }, WorkIssues = { issue1, issue4 }, Projects = { } });
53+
54+
session.Flush();
55+
transaction.Commit();
56+
}
57+
}
58+
59+
[Test]
60+
public async Task WhereClauseAsync()
61+
{
62+
await (AreEqualAsync(
63+
// Conditional style
64+
q => q.Where(e => (e.ReviewAsPrimary ? e.ReviewIssues : e.Projects.Any() ? e.Projects.SelectMany(x => x.Issues) : e.WorkIssues).Any(i => i.Client.Name == "Beta")),
65+
// Expected
66+
q => q.Where(e => e.ReviewAsPrimary ? e.ReviewIssues.Any(i => i.Client.Name == "Beta") : e.Projects.Any() ? e.Projects.SelectMany(x => x.Issues).Any(i => i.Client.Name == "Beta") : e.WorkIssues.Any(i => i.Client.Name == "Beta"))
67+
));
68+
}
69+
70+
[Test]
71+
public async Task SelectClauseAsync()
72+
{
73+
await (AreEqualAsync(
74+
// Conditional style
75+
q => q.OrderBy(e => e.Name)
76+
.Select(e => (e.ReviewAsPrimary ? e.ReviewIssues : e.Projects.Any() ? e.Projects.SelectMany(x => x.Issues) : e.WorkIssues).Any(i => i.Client.Name == "Beta")),
77+
// Expected
78+
q => q.OrderBy(e => e.Name)
79+
.Select(e => e.ReviewAsPrimary ? e.ReviewIssues.Any(i => i.Client.Name == "Beta") : e.Projects.Any() ? e.Projects.SelectMany(x => x.Issues).Any(i => i.Client.Name == "Beta") : e.WorkIssues.Any(i => i.Client.Name == "Beta"))
80+
));
81+
}
82+
83+
[Test]
84+
public async Task SelectClauseToAnonAsync()
85+
{
86+
await (AreEqualAsync(
87+
// Conditional style
88+
q => q.OrderBy(e => e.Name)
89+
.Select(e => new { e.Name, Beta = (e.ReviewAsPrimary ? e.ReviewIssues : e.Projects.Any() ? e.Projects.SelectMany(x => x.Issues) : e.WorkIssues).Any(i => i.Client.Name == "Beta") }),
90+
// Expected
91+
q => q.OrderBy(e => e.Name)
92+
.Select(e => new { e.Name, Beta = e.ReviewAsPrimary ? e.ReviewIssues.Any(i => i.Client.Name == "Beta") : e.Projects.Any() ? e.Projects.SelectMany(x => x.Issues).Any(i => i.Client.Name == "Beta") : e.WorkIssues.Any(i => i.Client.Name == "Beta") })
93+
));
94+
}
95+
96+
[Test]
97+
public async Task OrderByClauseAsync()
98+
{
99+
await (AreEqualAsync(
100+
// Conditional style
101+
q => q.OrderBy(e => (e.ReviewAsPrimary ? e.ReviewIssues : e.Projects.Any() ? e.Projects.SelectMany(x => x.Issues) : e.WorkIssues).Count())
102+
.ThenBy(p => p.Name)
103+
.Select(p => p.Name),
104+
// Expected
105+
q => q.OrderBy(e => e.ReviewAsPrimary ? e.ReviewIssues.Count() : e.Projects.Any() ? e.Projects.SelectMany(x => x.Issues).Count() : e.WorkIssues.Count())
106+
.ThenBy(p => p.Name)
107+
.Select(p => p.Name)
108+
));
109+
}
110+
111+
[Test]
112+
public async Task GroupByClauseAsync()
113+
{
114+
await (AreEqualAsync(
115+
// Conditional style
116+
q => q.GroupBy(e => (e.ReviewAsPrimary ? e.ReviewIssues : e.Projects.Any() ? e.Projects.SelectMany(x => x.Issues) : e.WorkIssues).Count())
117+
.OrderBy(x => x.Key)
118+
.Select(grp => grp.Count()),
119+
// Expected
120+
q => q.GroupBy(e => e.ReviewAsPrimary ? e.ReviewIssues.Count() : e.Projects.Any() ? e.Projects.SelectMany(x => x.Issues).Count() : e.WorkIssues.Count())
121+
.OrderBy(x => x.Key)
122+
.Select(grp => grp.Count())
123+
));
124+
}
125+
}
126+
}

src/NHibernate.Test/NHSpecificTest/GH1879/Entity.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ public class Employee
2121
public virtual string Name { get; set; }
2222

2323
public virtual bool ReviewAsPrimary { get; set; }
24+
public virtual ICollection<Project> Projects { get; set; } = new List<Project>();
2425
public virtual ICollection<Issue> WorkIssues { get; set; } = new List<Issue>();
2526
public virtual ICollection<Issue> ReviewIssues { get; set; } = new List<Issue>();
2627
}
@@ -33,6 +34,7 @@ public class Project
3334
public virtual Client Client { get; set; }
3435
public virtual Client BillingClient { get; set; }
3536
public virtual CorporateClient CorporateClient { get; set; }
37+
public virtual ICollection<Issue> Issues { get; set; } = new List<Issue>();
3638
}
3739

3840
public enum EmailPref

src/NHibernate.Test/NHSpecificTest/GH1879/FixtureByCode.cs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,12 @@ protected override HbmMapping GetMappings()
3131
rc.ManyToOne(x => x.Client, m => m.Column("ClientId"));
3232
rc.ManyToOne(x => x.BillingClient, m => m.Column("BillingClientId"));
3333
rc.ManyToOne(x => x.CorporateClient, m => m.Column("CorporateClientId"));
34+
rc.Set(x => x.Issues,
35+
m =>
36+
{
37+
m.Key(k => k.Column(c => c.Name("ProjectId")) );
38+
},
39+
rel => rel.OneToMany());
3440
});
3541
mapper.Class<Issue>(rc =>
3642
{
@@ -51,6 +57,14 @@ protected override HbmMapping GetMappings()
5157
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
5258
rc.Property(x => x.Name);
5359
rc.Property(x => x.ReviewAsPrimary);
60+
rc.Set(x => x.Projects,
61+
m =>
62+
{
63+
m.Table("EmployeesToProjects");
64+
m.Cascade(Mapping.ByCode.Cascade.All | Mapping.ByCode.Cascade.DeleteOrphans);
65+
m.Key(k => k.Column(c => c.Name("EmployeeId")) );
66+
},
67+
rel => rel.ManyToMany(m => m.Column("ProjectId")));
5468
rc.Set(x => x.WorkIssues,
5569
m =>
5670
{
Lines changed: 115 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
using System.Linq;
2+
using NUnit.Framework;
3+
4+
namespace NHibernate.Test.NHSpecificTest.GH1879
5+
{
6+
[TestFixture]
7+
public class NestedConditionalThenMethodCall : GH1879BaseFixture<Employee>
8+
{
9+
/// <inheritdoc />
10+
protected override void OnSetUp()
11+
{
12+
using (var session = OpenSession())
13+
using (var transaction = session.BeginTransaction())
14+
{
15+
var clientA = new Client { Name = "Alpha" };
16+
var clientB = new Client { Name = "Beta" };
17+
session.Save(clientA);
18+
session.Save(clientB);
19+
20+
var projectA = new Project { Name = "Apple" };
21+
var projectB = new Project { Name = "Banana" };
22+
var projectC = new Project { Name = "Cherry" };
23+
session.Save(projectA);
24+
session.Save(projectB);
25+
session.Save(projectC);
26+
27+
var issue1 = new Issue { Name = "1", Client = null, Project = null };
28+
var issue2 = new Issue { Name = "2", Client = clientA, Project = projectA };
29+
var issue3 = new Issue { Name = "3", Client = clientA, Project = projectA };
30+
var issue4 = new Issue { Name = "4", Client = clientA, Project = projectB };
31+
var issue5 = new Issue { Name = "5", Client = clientB, Project = projectC };
32+
session.Save(issue1);
33+
session.Save(issue2);
34+
session.Save(issue3);
35+
session.Save(issue4);
36+
session.Save(issue5);
37+
38+
session.Save(new Employee { Name = "Andy", ReviewAsPrimary = true, ReviewIssues = { issue1, issue2, issue5 }, WorkIssues = { issue3 }, Projects = { projectA, projectB } });
39+
session.Save(new Employee { Name = "Bart", ReviewAsPrimary = false, ReviewIssues = { issue3 }, WorkIssues = { issue4, issue5 }, Projects = { projectB, projectC } });
40+
session.Save(new Employee { Name = "Carl", ReviewAsPrimary = true, ReviewIssues = { issue3 }, WorkIssues = { issue1, issue4, issue5 }, Projects = { projectC } });
41+
session.Save(new Employee { Name = "Dorn", ReviewAsPrimary = false, ReviewIssues = { issue3 }, WorkIssues = { issue1, issue4 }, Projects = { } });
42+
43+
session.Flush();
44+
transaction.Commit();
45+
}
46+
}
47+
48+
[Test]
49+
public void WhereClause()
50+
{
51+
AreEqual(
52+
// Conditional style
53+
q => q.Where(e => (e.ReviewAsPrimary ? e.ReviewIssues : e.Projects.Any() ? e.Projects.SelectMany(x => x.Issues) : e.WorkIssues).Any(i => i.Client.Name == "Beta")),
54+
// Expected
55+
q => q.Where(e => e.ReviewAsPrimary ? e.ReviewIssues.Any(i => i.Client.Name == "Beta") : e.Projects.Any() ? e.Projects.SelectMany(x => x.Issues).Any(i => i.Client.Name == "Beta") : e.WorkIssues.Any(i => i.Client.Name == "Beta"))
56+
);
57+
}
58+
59+
[Test]
60+
public void SelectClause()
61+
{
62+
AreEqual(
63+
// Conditional style
64+
q => q.OrderBy(e => e.Name)
65+
.Select(e => (e.ReviewAsPrimary ? e.ReviewIssues : e.Projects.Any() ? e.Projects.SelectMany(x => x.Issues) : e.WorkIssues).Any(i => i.Client.Name == "Beta")),
66+
// Expected
67+
q => q.OrderBy(e => e.Name)
68+
.Select(e => e.ReviewAsPrimary ? e.ReviewIssues.Any(i => i.Client.Name == "Beta") : e.Projects.Any() ? e.Projects.SelectMany(x => x.Issues).Any(i => i.Client.Name == "Beta") : e.WorkIssues.Any(i => i.Client.Name == "Beta"))
69+
);
70+
}
71+
72+
[Test]
73+
public void SelectClauseToAnon()
74+
{
75+
AreEqual(
76+
// Conditional style
77+
q => q.OrderBy(e => e.Name)
78+
.Select(e => new { e.Name, Beta = (e.ReviewAsPrimary ? e.ReviewIssues : e.Projects.Any() ? e.Projects.SelectMany(x => x.Issues) : e.WorkIssues).Any(i => i.Client.Name == "Beta") }),
79+
// Expected
80+
q => q.OrderBy(e => e.Name)
81+
.Select(e => new { e.Name, Beta = e.ReviewAsPrimary ? e.ReviewIssues.Any(i => i.Client.Name == "Beta") : e.Projects.Any() ? e.Projects.SelectMany(x => x.Issues).Any(i => i.Client.Name == "Beta") : e.WorkIssues.Any(i => i.Client.Name == "Beta") })
82+
);
83+
}
84+
85+
[Test]
86+
public void OrderByClause()
87+
{
88+
AreEqual(
89+
// Conditional style
90+
q => q.OrderBy(e => (e.ReviewAsPrimary ? e.ReviewIssues : e.Projects.Any() ? e.Projects.SelectMany(x => x.Issues) : e.WorkIssues).Count())
91+
.ThenBy(p => p.Name)
92+
.Select(p => p.Name),
93+
// Expected
94+
q => q.OrderBy(e => e.ReviewAsPrimary ? e.ReviewIssues.Count() : e.Projects.Any() ? e.Projects.SelectMany(x => x.Issues).Count() : e.WorkIssues.Count())
95+
.ThenBy(p => p.Name)
96+
.Select(p => p.Name)
97+
);
98+
}
99+
100+
[Test]
101+
public void GroupByClause()
102+
{
103+
AreEqual(
104+
// Conditional style
105+
q => q.GroupBy(e => (e.ReviewAsPrimary ? e.ReviewIssues : e.Projects.Any() ? e.Projects.SelectMany(x => x.Issues) : e.WorkIssues).Count())
106+
.OrderBy(x => x.Key)
107+
.Select(grp => grp.Count()),
108+
// Expected
109+
q => q.GroupBy(e => e.ReviewAsPrimary ? e.ReviewIssues.Count() : e.Projects.Any() ? e.Projects.SelectMany(x => x.Issues).Count() : e.WorkIssues.Count())
110+
.OrderBy(x => x.Key)
111+
.Select(grp => grp.Count())
112+
);
113+
}
114+
}
115+
}

0 commit comments

Comments
 (0)