Skip to content

Commit bc7e5c3

Browse files
committed
Use table group joins for many-to-many in Criteria and Entity loaders
1 parent d419ab3 commit bc7e5c3

18 files changed

+499
-255
lines changed

src/NHibernate.Test/Async/NHSpecificTest/GH1994/Fixture.cs renamed to src/NHibernate.Test/Async/NHSpecificTest/GH1994/ManyToManyFilteredFixture.cs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ namespace NHibernate.Test.NHSpecificTest.GH1994
2020
{
2121
using System.Threading.Tasks;
2222
[TestFixture]
23-
public class FixtureAsync : BugTestCase
23+
public class ManyToManyFilteredFixtureAsync : BugTestCase
2424
{
2525
protected override void OnSetUp()
2626
{
@@ -150,5 +150,37 @@ public async Task TestQueryOverRestrictionWithClauseAsync()
150150
Assert.That(query[0].Documents.Count, Is.EqualTo(1), "filtered asset documents");
151151
}
152152
}
153+
154+
[Test]
155+
public async Task LazyLoadAsync()
156+
{
157+
if(Dialect is PostgreSQLDialect)
158+
Assert.Ignore("Dialect doesn't support 0/1 to bool implicit cast");
159+
160+
using (var s = OpenSession())
161+
{
162+
var asset = await (s.Query<Asset>().FirstAsync());
163+
Assert.That(asset.Documents.Count, Is.EqualTo(2));
164+
Assert.That(asset.DocumentsBag.Count, Is.EqualTo(2));
165+
Assert.That(asset.DocumentsFiltered.Count, Is.EqualTo(1));
166+
}
167+
}
168+
169+
[Test]
170+
public async Task LazyLoadFilteredAsync()
171+
{
172+
if(Dialect is PostgreSQLDialect)
173+
Assert.Ignore("Dialect doesn't support 0/1 to bool implicit cast");
174+
175+
using (var s = OpenSession())
176+
{
177+
s.EnableFilter("deletedFilter").SetParameter("deletedParam", false);
178+
179+
var asset = await (s.Query<Asset>().FirstAsync());
180+
Assert.That(asset.Documents.Count, Is.EqualTo(1));
181+
Assert.That(asset.DocumentsBag.Count, Is.EqualTo(1));
182+
Assert.That(asset.DocumentsFiltered.Count, Is.EqualTo(1));
183+
}
184+
}
153185
}
154186
}

src/NHibernate.Test/Async/NHSpecificTest/NH750/Fixture.cs renamed to src/NHibernate.Test/Async/NHSpecificTest/NH750/ManyToManyNotFoundIgnoreFixture.cs

Lines changed: 87 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,55 @@
1010

1111
using System;
1212
using NHibernate.Cfg;
13+
using NHibernate.Criterion;
14+
using NHibernate.Transform;
1315
using NUnit.Framework;
1416

1517
namespace NHibernate.Test.NHSpecificTest.NH750
1618
{
1719
using System.Threading.Tasks;
1820
[TestFixture]
19-
public class FixtureAsync : BugTestCase
21+
public class ManyToManyNotFoundIgnoreFixtureAsync : BugTestCase
2022
{
23+
private int id1;
24+
private int id2;
25+
26+
protected override void OnSetUp()
27+
{
28+
Drive dr1 = new Drive("Drive 1");
29+
Drive dr2 = new Drive("Drive 2");
30+
Drive dr3 = new Drive("Drive 3");
31+
Device dv1 = new Device("Device 1");
32+
Device dv2 = new Device("Device 2");
33+
using (var s = Sfi.OpenSession())
34+
using (var t = s.BeginTransaction())
35+
{
36+
s.Save(dr1);
37+
s.Save(dr2);
38+
s.Save(dr3);
39+
dv1.Drives.Add(dr1);
40+
dv1.Drives.Add(dr2);
41+
dv2.Drives.Add(dr1);
42+
dv2.Drives.Add(dr3);
43+
44+
id1 = (int) s.Save(dv1);
45+
id2 = (int) s.Save(dv2);
46+
s.Flush();
47+
48+
s.Clear();
49+
s.Delete(dr3);
50+
t.Commit();
51+
}
52+
}
53+
2154
protected override void OnTearDown()
2255
{
2356
using (ISession s = Sfi.OpenSession())
57+
using (var t = s.BeginTransaction())
2458
{
2559
s.Delete("from Device");
2660
s.Delete("from Drive");
27-
s.Flush();
61+
t.Commit();
2862
}
2963
}
3064

@@ -37,51 +71,17 @@ protected override void Configure(Configuration configuration)
3771
[Test]
3872
public async Task DeviceOfDriveAsync()
3973
{
40-
int[] dvSavedId = new int[2];
41-
Drive dr1 = new Drive("Drive 1");
42-
Drive dr2 = new Drive("Drive 2");
43-
Drive dr3 = new Drive("Drive 3");
44-
Device dv1 = new Device("Device 1");
45-
Device dv2 = new Device("Device 2");
74+
Device dv1;
75+
Device dv2;
4676
using (ISession s = Sfi.OpenSession())
4777
{
48-
await (s.SaveAsync(dr1));
49-
await (s.SaveAsync(dr2));
50-
await (s.SaveAsync(dr3));
51-
dvSavedId[0] = (int) await (s.SaveAsync(dv1));
52-
dvSavedId[1] = (int) await (s.SaveAsync(dv2));
53-
await (s.FlushAsync());
78+
dv1 = (Device) await (s.LoadAsync(typeof(Device), id1));
79+
dv2 = (Device) await (s.LoadAsync(typeof(Device), id2));
5480
}
5581

56-
dv1.Drives.Add(dr1);
57-
dv1.Drives.Add(dr2);
58-
dv2.Drives.Add(dr1);
59-
dv2.Drives.Add(dr3);
60-
using (ISession s = Sfi.OpenSession())
61-
{
62-
dvSavedId[0] = (int) await (s.SaveAsync(dv1));
63-
dvSavedId[1] = (int) await (s.SaveAsync(dv2));
64-
await (s.FlushAsync());
65-
}
66-
dv1 = null;
67-
dv2 = null;
68-
using (ISession s = Sfi.OpenSession())
69-
{
70-
await (s.DeleteAsync(dr3));
71-
await (s.FlushAsync());
72-
dv1 = (Device) await (s.LoadAsync(typeof(Device), dvSavedId[0]));
73-
dv2 = (Device) await (s.LoadAsync(typeof(Device), dvSavedId[1]));
74-
}
75-
Assert.AreEqual(2, dv1.Drives.Count);
82+
Assert.That(dv1.Drives, Has.Count.EqualTo(2).And.None.Null);
7683
// Verify one is missing
77-
Assert.AreEqual(1, dv2.Drives.Count);
78-
// Verify dv1 unchanged
79-
Assert.IsTrue(dv1.Drives.Contains(dr1));
80-
Assert.IsTrue(dv1.Drives.Contains(dr2));
81-
82-
// Verify dv2
83-
Assert.IsTrue(dv2.Drives.Contains(dr1));
84-
Assert.IsFalse(dv2.Drives.Contains(dr3));
84+
Assert.That(dv2.Drives, Has.Count.EqualTo(1).And.None.Null);
8585

8686
//Make sure that flush didn't touch not-found="ignore" records for not modified collection
8787
using (var s = Sfi.OpenSession())
@@ -99,7 +99,7 @@ public async Task DeviceOfDriveAsync()
9999
using (var t = s.BeginTransaction())
100100
{
101101
dv2 = await (s.GetAsync<Device>(dv2.Id));
102-
dv2.Drives.Add(dr2);
102+
dv2.Drives.Add(dv1.Drives[1]);
103103
await (t.CommitAsync());
104104
}
105105

@@ -120,5 +120,49 @@ async Task VerifyResultAsync(int expectedInCollection, int expectedInDb, string
120120
}
121121
}
122122
}
123+
124+
[Test]
125+
public async Task QueryOverFetchAsync()
126+
{
127+
using (var s = OpenSession())
128+
{
129+
var dv2 = await (s.QueryOver<Device>()
130+
.Fetch(SelectMode.Fetch, x => x.Drives)
131+
.Where(Restrictions.IdEq(id2))
132+
.TransformUsing(Transformers.DistinctRootEntity)
133+
.SingleOrDefaultAsync());
134+
135+
Assert.That(NHibernateUtil.IsInitialized(dv2.Drives), Is.True);
136+
Assert.That(dv2.Drives, Has.Count.EqualTo(1).And.None.Null);
137+
}
138+
}
139+
140+
[Test]
141+
public async Task HqlFetchAsync()
142+
{
143+
using (var s = OpenSession())
144+
{
145+
var dv2 = await (s.CreateQuery("from Device d left join fetch d.Drives where d.id = :id")
146+
.SetResultTransformer(Transformers.DistinctRootEntity)
147+
.SetParameter("id", id2)
148+
.UniqueResultAsync<Device>());
149+
150+
Assert.That(NHibernateUtil.IsInitialized(dv2.Drives), Is.True);
151+
Assert.That(dv2.Drives, Has.Count.EqualTo(1).And.None.Null);
152+
}
153+
}
154+
155+
[Test]
156+
public async Task LazyLoadAsync()
157+
{
158+
using (var s = OpenSession())
159+
{
160+
var dv2 = await (s.GetAsync<Device>(id2));
161+
await (NHibernateUtil.InitializeAsync(dv2.Drives));
162+
163+
Assert.That(NHibernateUtil.IsInitialized(dv2.Drives), Is.True);
164+
Assert.That(dv2.Drives, Has.Count.EqualTo(1).And.None.Null);
165+
}
166+
}
123167
}
124168
}

src/NHibernate.Test/Async/PropertyRef/ManyToManyPropertyRefFixture.cs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,22 @@
88
//------------------------------------------------------------------------------
99

1010

11+
using System.Linq;
1112
using NHibernate.Criterion;
13+
using NHibernate.Linq;
1214
using NUnit.Framework;
1315

1416
namespace NHibernate.Test.PropertyRef
1517
{
1618
using System.Threading.Tasks;
17-
[TestFixture]
19+
[TestFixture(Description = "NH-2180 (GH-1214)")]
1820
public class ManyToManyPropertyRefFixtureAsync : TestCase
1921
{
2022
protected override string[] Mappings => new[] { "PropertyRef.ManyToManyWithPropertyRef.hbm.xml" };
2123

2224
protected override string MappingsAssembly => "NHibernate.Test";
2325

24-
private object _manyAId;
26+
private long _manyAId;
2527

2628
protected override void OnSetUp()
2729
{
@@ -34,7 +36,7 @@ protected override void OnSetUp()
3436
var manyB2 = new ManyB { Number = 8, Value = "a value of b2" };
3537
var manyB3 = new ManyB { Number = 12, Value = "a value of b3" };
3638

37-
_manyAId = session.Save(manyA);
39+
_manyAId = (long) session.Save(manyA);
3840
session.Save(manyB1);
3941
session.Save(manyB2);
4042
session.Save(manyB3);
@@ -144,5 +146,20 @@ bei NHibernate.Type.EntityType.LoadByUniqueKey(String entityName, String uniqueK
144146

145147
Assert.That(loadedManyA.ManyBs, Has.Count.EqualTo(3).And.None.Null);
146148
}
149+
150+
[Test]
151+
public async Task LinqFetchAsync()
152+
{
153+
using (var session = OpenSession())
154+
{
155+
var manyA = (await (session
156+
.Query<ManyA>()
157+
.Where(a => a.Id == _manyAId)
158+
.FetchMany(a => a.ManyBs)
159+
.ToListAsync()))
160+
.First();
161+
Assert.That(manyA.ManyBs, Has.Count.EqualTo(3).And.None.Null);
162+
}
163+
}
147164
}
148165
}

src/NHibernate.Test/NHSpecificTest/GH1994/Fixture.cs renamed to src/NHibernate.Test/NHSpecificTest/GH1994/ManyToManyFilteredFixture.cs

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
namespace NHibernate.Test.NHSpecificTest.GH1994
1010
{
1111
[TestFixture]
12-
public class Fixture : BugTestCase
12+
public class ManyToManyFilteredFixture : BugTestCase
1313
{
1414
protected override void OnSetUp()
1515
{
@@ -139,5 +139,37 @@ public void TestQueryOverRestrictionWithClause()
139139
Assert.That(query[0].Documents.Count, Is.EqualTo(1), "filtered asset documents");
140140
}
141141
}
142+
143+
[Test]
144+
public void LazyLoad()
145+
{
146+
if(Dialect is PostgreSQLDialect)
147+
Assert.Ignore("Dialect doesn't support 0/1 to bool implicit cast");
148+
149+
using (var s = OpenSession())
150+
{
151+
var asset = s.Query<Asset>().First();
152+
Assert.That(asset.Documents.Count, Is.EqualTo(2));
153+
Assert.That(asset.DocumentsBag.Count, Is.EqualTo(2));
154+
Assert.That(asset.DocumentsFiltered.Count, Is.EqualTo(1));
155+
}
156+
}
157+
158+
[Test]
159+
public void LazyLoadFiltered()
160+
{
161+
if(Dialect is PostgreSQLDialect)
162+
Assert.Ignore("Dialect doesn't support 0/1 to bool implicit cast");
163+
164+
using (var s = OpenSession())
165+
{
166+
s.EnableFilter("deletedFilter").SetParameter("deletedParam", false);
167+
168+
var asset = s.Query<Asset>().First();
169+
Assert.That(asset.Documents.Count, Is.EqualTo(1));
170+
Assert.That(asset.DocumentsBag.Count, Is.EqualTo(1));
171+
Assert.That(asset.DocumentsFiltered.Count, Is.EqualTo(1));
172+
}
173+
}
142174
}
143175
}

src/NHibernate.Test/NHSpecificTest/NH750/Device.cs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,18 @@ public string Manifacturer
3333
}
3434

3535
private IList<Drive> _drives = new List<Drive>();
36+
private IList<Drive> _drivesNotIgnored = new List<Drive>();
3637

3738
public IList<Drive> Drives
3839
{
3940
get { return _drives; }
4041
set { _drives = value; }
4142
}
43+
44+
public IList<Drive> DrivesNotIgnored
45+
{
46+
get => _drivesNotIgnored;
47+
set => _drivesNotIgnored = value;
48+
}
4249
}
43-
}
50+
}

0 commit comments

Comments
 (0)