Skip to content

Commit 4a7251d

Browse files
Support mixed formulas and columns
Many mapping elements allow to define their columns or formulas by nested elements, but most of them do not support having both nested columns and formulas. Follow-up to NH-2117, which has added this support to one-to-many.
1 parent 2f8f317 commit 4a7251d

File tree

12 files changed

+887
-136
lines changed

12 files changed

+887
-136
lines changed

doc/reference/modules/example_mappings.xml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -496,7 +496,6 @@ alter table line_items
496496

497497
</sect2>
498498

499-
<!-- This example is not supported by NHibernate, because HbmManyToMany lacks a ColumnsAndFormulas handling
500499
<sect2 id="example-mappings-miscellaneous-m2mcomposite">
501500
<title>Many-to-many with shared composite key attribute</title>
502501

@@ -535,8 +534,12 @@ alter table line_items
535534
</set>
536535
</class>]]></programlisting>
537536

537+
<para>
538+
This case requires mixing column and formula under the <literal>&lt;many-to-many&gt;</literal>
539+
element, which is supported only since NHibernate 5.2.
540+
</para>
541+
538542
</sect2>
539-
-->
540543

541544
<sect2 id="example-mappings-miscellaneous-contentdiscriminator">
542545
<title>Content based discrimination</title>
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
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.Collections.Generic;
13+
using System.Linq;
14+
using NHibernate.Dialect;
15+
using NUnit.Framework;
16+
using NHibernate.Linq;
17+
18+
namespace NHibernate.Test.NHSpecificTest.GH1759
19+
{
20+
using System.Threading.Tasks;
21+
[TestFixture]
22+
public class ColumnsAndFormulasFixtureAsync : BugTestCase
23+
{
24+
// In fact most of the test happens at mapping compilation.
25+
protected override bool AppliesTo(Dialect.Dialect dialect)
26+
{
27+
// Uses some formulas with SLQ-Server transact SQL functions
28+
return dialect is MsSql2000Dialect;
29+
}
30+
31+
protected override void OnSetUp()
32+
{
33+
using (var session = OpenSession())
34+
using (var transaction = session.BeginTransaction())
35+
{
36+
var bob =
37+
new User
38+
{
39+
Name = "Bob",
40+
Org = "Eg",
41+
DepartureDate = DateTime.Parse("2012-07-01"),
42+
Hiring = new DateSpan
43+
{
44+
Date1 = DateTime.Parse("2001-01-01")
45+
}
46+
};
47+
session.Save(bob);
48+
49+
var sally =
50+
new User
51+
{
52+
Name = "Sally",
53+
Org = "Eg",
54+
Hiring = new DateSpan
55+
{
56+
Date1 = DateTime.Parse("2006-01-08")
57+
}
58+
};
59+
session.Save(sally);
60+
61+
var g1 = new Group { Name = "Salesperson", Org = "Eg" };
62+
g1.DateSpans.Add(new DateSpan { Date1 = DateTime.Parse("2000-12-31") });
63+
session.Save(g1);
64+
65+
var g2 = new Group { Name = "Manager", Org = "Eg" };
66+
session.Save(g2);
67+
68+
bob.Groups.Add(g1);
69+
g1.CommentsByUser.Add(bob, "He is gone, maybe he can be cleaned-up from the group.");
70+
sally.Groups.Add(g1);
71+
sally.Groups.Add(g2);
72+
73+
session.Flush();
74+
75+
// Needs to be done after the Flush, because this creates a circular reference.
76+
bob.MainGroupName = "Salesperson";
77+
sally.MainGroupName = "Salesperson";
78+
79+
transaction.Commit();
80+
}
81+
}
82+
83+
protected override void OnTearDown()
84+
{
85+
using (var session = OpenSession())
86+
using (var transaction = session.BeginTransaction())
87+
{
88+
// HQL "delete from" does neither handle the many-to-many table, nor the element table.
89+
// So using ISession.Delete instead of ISession.CreateQuery("delete...
90+
session.Delete("from User");
91+
session.Delete("from Group");
92+
93+
transaction.Commit();
94+
}
95+
}
96+
97+
[Test]
98+
public async Task CheckManyToManyAsync()
99+
{
100+
using (var session = OpenSession())
101+
using (var tx = session.BeginTransaction())
102+
{
103+
var bob = await (session.Query<User>().SingleAsync(u => u.Name == "Bob" && u.Org == "Eg"));
104+
var sally = await (session.Query<User>().SingleAsync(u => u.Name == "Sally" && u.Org == "Eg"));
105+
var salesperson = await (session.Query<Group>().SingleAsync(u => u.Name == "Salesperson" && u.Org == "Eg"));
106+
var manager = await (session.Query<Group>().SingleAsync(u => u.Name == "Manager" && u.Org == "Eg"));
107+
108+
Assert.That(
109+
bob.Groups,
110+
Has.Count.EqualTo(1)
111+
.And.One.EqualTo(salesperson));
112+
Assert.That(
113+
sally.Groups,
114+
Has.Count.EqualTo(2)
115+
.And.One.EqualTo(salesperson)
116+
.And.One.EqualTo(manager));
117+
Assert.That(
118+
salesperson.Users,
119+
Has.Count.EqualTo(2)
120+
.And.One.EqualTo(bob)
121+
.And.One.EqualTo(sally));
122+
Assert.That(
123+
manager.Users,
124+
Has.Count.EqualTo(1)
125+
.And.One.EqualTo(sally));
126+
127+
await (tx.CommitAsync());
128+
}
129+
}
130+
131+
[Test]
132+
public async Task CheckPropertyAsync()
133+
{
134+
using (var session = OpenSession())
135+
using (var tx = session.BeginTransaction())
136+
{
137+
var bob = await (session.Query<User>().SingleAsync(u => u.Name == "Bob" && u.Org == "Eg"));
138+
var sally = await (session.Query<User>().SingleAsync(u => u.Name == "Sally" && u.Org == "Eg"));
139+
140+
Assert.That(
141+
bob.Hiring,
142+
Has.Property(nameof(DateSpan.Date1)).EqualTo(DateTime.Parse("2001-01-01"))
143+
.And.Property(nameof(DateSpan.Date2)).EqualTo(bob.DepartureDate));
144+
Assert.That(
145+
sally.Hiring,
146+
Has.Property(nameof(DateSpan.Date1)).EqualTo(DateTime.Parse("2006-01-08"))
147+
.And.Property(nameof(DateSpan.Date2)).EqualTo(sally.DepartureDate));
148+
149+
sally.DepartureDate = DateTime.Today;
150+
151+
await (tx.CommitAsync());
152+
}
153+
154+
using (var session = OpenSession())
155+
using (var tx = session.BeginTransaction())
156+
{
157+
var sally = await (session.Query<User>().SingleAsync(u => u.Name == "Sally" && u.Org == "Eg"));
158+
Assert.That(sally.DepartureDate, Is.Not.Null);
159+
Assert.That(
160+
sally.Hiring,
161+
Has.Property(nameof(DateSpan.Date1)).EqualTo(DateTime.Parse("2006-01-08"))
162+
.And.Property(nameof(DateSpan.Date2)).EqualTo(sally.DepartureDate));
163+
164+
await (tx.CommitAsync());
165+
}
166+
}
167+
168+
[Test]
169+
public async Task CheckElementAsync()
170+
{
171+
using (var session = OpenSession())
172+
using (var tx = session.BeginTransaction())
173+
{
174+
var salesperson = await (session.Query<Group>().SingleAsync(u => u.Name == "Salesperson" && u.Org == "Eg"));
175+
176+
Assert.That(
177+
salesperson.DateSpans,
178+
Has.Count.GreaterThan(0)
179+
.And.All.Property(nameof(DateSpan.Date2)).EqualTo(DateTime.Parse("2000-12-31").AddYears(2)));
180+
181+
await (tx.CommitAsync());
182+
}
183+
}
184+
185+
[Test, Ignore("Needs an unrelated additional simple fix in OneToManyPersister")]
186+
public async Task CheckMapKeyAsync()
187+
{
188+
using (var session = OpenSession())
189+
using (var tx = session.BeginTransaction())
190+
{
191+
var salesperson = await (session.Query<Group>().SingleAsync(u => u.Name == "Salesperson" && u.Org == "Eg"));
192+
193+
Assert.That(
194+
salesperson.UsersByHiring,
195+
Has.Count.EqualTo(2)
196+
.And.One.Property(nameof(KeyValuePair<DateSpan, User>.Key)).Property(nameof(DateSpan.Date2)).Null
197+
.And.One.Property(nameof(KeyValuePair<DateSpan, User>.Key)).Property(nameof(DateSpan.Date2)).EqualTo(DateTime.Parse("2012-07-01")));
198+
199+
await (tx.CommitAsync());
200+
}
201+
}
202+
203+
[Test]
204+
public async Task CheckMapKeyManyToManyAsync()
205+
{
206+
using (var session = OpenSession())
207+
using (var tx = session.BeginTransaction())
208+
{
209+
var bob = await (session.Query<User>().SingleAsync(u => u.Name == "Bob" && u.Org == "Eg"));
210+
var salesperson = await (session.Query<Group>().SingleAsync(u => u.Name == "Salesperson" && u.Org == "Eg"));
211+
212+
Assert.That(
213+
salesperson.CommentsByUser,
214+
Has.Count.EqualTo(1)
215+
.And.One.Property(nameof(KeyValuePair<User, User>.Key)).EqualTo(bob).And.Property(nameof(KeyValuePair<User, User>.Value)).Length.GreaterThan(0));
216+
217+
await (tx.CommitAsync());
218+
}
219+
}
220+
}
221+
}

0 commit comments

Comments
 (0)