Skip to content

Commit 3e19e6b

Browse files
committed
Implement universal query batch
1 parent f400ccb commit 3e19e6b

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+2626
-179
lines changed
Lines changed: 292 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,292 @@
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;
13+
using System.Collections.Generic;
14+
using System.Linq;
15+
using NHibernate.Cfg.MappingSchema;
16+
using NHibernate.Linq;
17+
using NHibernate.Mapping.ByCode;
18+
using NHibernate.Multi;
19+
using NHibernate.Transform;
20+
using NUnit.Framework;
21+
22+
namespace NHibernate.Test.Futures
23+
{
24+
using System.Threading.Tasks;
25+
using System.Threading;
26+
[TestFixture]
27+
public class QueryBatchFixtureAsync : TestCaseMappingByCode
28+
{
29+
private Guid _parentId;
30+
31+
[Test]
32+
public async Task CanCombineCriteriaAndHqlInBatchAsync()
33+
{
34+
using (var session = OpenSession())
35+
{
36+
var batch = session
37+
.CreateQueryBatch()
38+
39+
.Add<int>(
40+
session
41+
.QueryOver<EntityComplex>()
42+
.Where(x => x.Version >= 0)
43+
.TransformUsing(new ListTransformerToInt()))
44+
45+
.Add("queryOver", session.QueryOver<EntityComplex>().Where(x => x.Version >= 1))
46+
47+
.Add(session.Query<EntityComplex>().Where(ec => ec.Version > 2))
48+
49+
.Add<EntitySimpleChild>("sql",
50+
session.CreateSQLQuery(
51+
$"select * from {nameof(EntitySimpleChild)}")
52+
.AddEntity(typeof(EntitySimpleChild)));
53+
54+
using (var sqlLog = new SqlLogSpy())
55+
{
56+
await (batch.GetResultAsync<int>(0, CancellationToken.None));
57+
await (batch.GetResultAsync<EntityComplex>("queryOver", CancellationToken.None));
58+
await (batch.GetResultAsync<EntityComplex>(2, CancellationToken.None));
59+
await (batch.GetResultAsync<EntitySimpleChild>("sql", CancellationToken.None));
60+
if (SupportsMultipleQueries)
61+
Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(1));
62+
}
63+
}
64+
}
65+
66+
[Test]
67+
public async Task CanFetchCollectionInBatchAsync()
68+
{
69+
using (var sqlLog = new SqlLogSpy())
70+
using (var session = OpenSession())
71+
{
72+
var batch = session.CreateQueryBatch();
73+
74+
var q1 = session.QueryOver<EntityComplex>()
75+
.Where(x => x.Version >= 0);
76+
77+
batch.Add(q1);
78+
batch.Add(session.Query<EntityComplex>().Fetch(c => c.ChildrenList));
79+
await (batch.ExecuteAsync(CancellationToken.None));
80+
81+
var parent = await (session.LoadAsync<EntityComplex>(_parentId));
82+
Assert.That(NHibernateUtil.IsInitialized(parent), Is.True);
83+
Assert.That(NHibernateUtil.IsInitialized(parent.ChildrenList), Is.True);
84+
if (SupportsMultipleQueries)
85+
Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(1));
86+
}
87+
}
88+
89+
[Test]
90+
public async Task OnAfterLoadAsync()
91+
{
92+
using (var session = OpenSession())
93+
{
94+
var batch = session.CreateQueryBatch();
95+
IList<EntityComplex> results = null;
96+
var batchItem = LinqBatchItem.Create(session.Query<EntityComplex>().WithOptions(o => o.SetCacheable(true)));
97+
batchItem.OnAfterLoad += list => results = list;
98+
batch.Add(batchItem);
99+
100+
await (batch.ExecuteAsync(CancellationToken.None));
101+
102+
Assert.That(results, Is.Not.Null);
103+
}
104+
105+
using (var sqlLog = new SqlLogSpy())
106+
using (var session = OpenSession())
107+
{
108+
var batch = session.CreateQueryBatch();
109+
IList<EntityComplex> results = null;
110+
var batchItem = LinqBatchItem.Create(session.Query<EntityComplex>().WithOptions(o => o.SetCacheable(true)));
111+
batchItem.OnAfterLoad += list => results = list;
112+
batch.Add(batchItem);
113+
114+
await (batch.ExecuteAsync(CancellationToken.None));
115+
116+
Assert.That(results, Is.Not.Null);
117+
Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(0), "Query is expected to be retrieved from cache");
118+
}
119+
}
120+
121+
#region Test Setup
122+
123+
protected override HbmMapping GetMappings()
124+
{
125+
var mapper = new ModelMapper();
126+
mapper.Class<EntityComplex>(
127+
rc =>
128+
{
129+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
130+
131+
rc.Version(ep => ep.Version, vm => { });
132+
133+
rc.Property(x => x.Name);
134+
135+
rc.Property(ep => ep.LazyProp, m => m.Lazy(true));
136+
137+
rc.ManyToOne(ep => ep.Child1, m => m.Column("Child1Id"));
138+
rc.ManyToOne(ep => ep.Child2, m => m.Column("Child2Id"));
139+
rc.ManyToOne(ep => ep.SameTypeChild, m => m.Column("SameTypeChildId"));
140+
141+
rc.Bag(
142+
ep => ep.ChildrenList,
143+
m =>
144+
{
145+
m.Cascade(Mapping.ByCode.Cascade.All);
146+
m.Inverse(true);
147+
},
148+
a => a.OneToMany());
149+
});
150+
151+
mapper.Class<EntitySimpleChild>(
152+
rc =>
153+
{
154+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
155+
rc.ManyToOne(x => x.Parent);
156+
rc.Property(x => x.Name);
157+
});
158+
mapper.Class<EntityEager>(
159+
rc =>
160+
{
161+
rc.Lazy(false);
162+
163+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
164+
rc.Property(x => x.Name);
165+
166+
rc.Bag(ep => ep.ChildrenListSubselect,
167+
m =>
168+
{
169+
m.Cascade(Mapping.ByCode.Cascade.All);
170+
m.Inverse(true);
171+
m.Fetch(CollectionFetchMode.Subselect);
172+
m.Lazy(CollectionLazy.NoLazy);
173+
},
174+
a => a.OneToMany());
175+
176+
rc.Bag(ep => ep.ChildrenListEager,
177+
m =>
178+
{
179+
m.Lazy(CollectionLazy.NoLazy);
180+
},
181+
a => a.OneToMany());
182+
});
183+
mapper.Class<EntitySubselectChild>(
184+
rc =>
185+
{
186+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
187+
rc.Property(x => x.Name);
188+
rc.ManyToOne(c => c.Parent);
189+
});
190+
191+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
192+
}
193+
194+
protected override void OnTearDown()
195+
{
196+
using (ISession session = OpenSession())
197+
using (ITransaction transaction = session.BeginTransaction())
198+
{
199+
session.Delete("from System.Object");
200+
201+
session.Flush();
202+
transaction.Commit();
203+
}
204+
}
205+
206+
protected override void OnSetUp()
207+
{
208+
using (var session = OpenSession())
209+
using (var transaction = session.BeginTransaction())
210+
{
211+
var child1 = new EntitySimpleChild
212+
{
213+
Name = "Child1",
214+
};
215+
var child2 = new EntitySimpleChild
216+
{
217+
Name = "Child2"
218+
};
219+
var complex = new EntityComplex
220+
{
221+
Name = "ComplexEnityParent",
222+
Child1 = child1,
223+
Child2 = child2,
224+
LazyProp = "SomeBigValue",
225+
SameTypeChild = new EntityComplex()
226+
{
227+
Name = "ComplexEntityChild"
228+
},
229+
};
230+
child1.Parent = child2.Parent = complex;
231+
232+
var eager = new EntityEager()
233+
{
234+
Name = "eager1",
235+
};
236+
237+
var eager2 = new EntityEager()
238+
{
239+
Name = "eager2",
240+
};
241+
eager.ChildrenListSubselect = new List<EntitySubselectChild>()
242+
{
243+
new EntitySubselectChild()
244+
{
245+
Name = "subselect1",
246+
Parent = eager,
247+
},
248+
new EntitySubselectChild()
249+
{
250+
Name = "subselect2",
251+
Parent = eager,
252+
},
253+
};
254+
255+
session.Save(child1);
256+
session.Save(child2);
257+
session.Save(complex.SameTypeChild);
258+
session.Save(complex);
259+
session.Save(eager);
260+
session.Save(eager2);
261+
262+
session.Flush();
263+
transaction.Commit();
264+
265+
_parentId = complex.Id;
266+
}
267+
}
268+
269+
public class ListTransformerToInt : IResultTransformer
270+
{
271+
public object TransformTuple(object[] tuple, string[] aliases)
272+
{
273+
return tuple.Length == 1 ? tuple[0] : tuple;
274+
}
275+
276+
public IList TransformList(IList collection)
277+
{
278+
return new List<int>()
279+
{
280+
1,
281+
2,
282+
3,
283+
4,
284+
};
285+
}
286+
}
287+
288+
private bool SupportsMultipleQueries => Sfi.ConnectionProvider.Driver.SupportsMultipleQueries;
289+
290+
#endregion Test Setup
291+
}
292+
}

0 commit comments

Comments
 (0)