Skip to content

Commit 8649f6e

Browse files
bahusoidfredericDelaporte
authored andcommitted
Implement universal query batch
1 parent e1565b4 commit 8649f6e

Some content is hidden

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

46 files changed

+2435
-144
lines changed
Lines changed: 293 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,293 @@
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 AfterLoadCallbackAsync()
91+
{
92+
using (var session = OpenSession())
93+
{
94+
var batch = session.CreateQueryBatch();
95+
IList<EntityComplex> results = null;
96+
int count = 0;
97+
batch.Add(session.Query<EntityComplex>().WithOptions(o => o.SetCacheable(true)), r => results = r);
98+
batch.Add(session.Query<EntityComplex>().WithOptions(o => o.SetCacheable(true)), ec => ec.Count(), r => count = r);
99+
await (batch.ExecuteAsync(CancellationToken.None));
100+
101+
Assert.That(results, Is.Not.Null);
102+
Assert.That(count, Is.GreaterThan(0));
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+
int count = 0;
111+
batch.Add(session.Query<EntityComplex>().WithOptions(o => o.SetCacheable(true)), r => results = r);
112+
batch.Add(session.Query<EntityComplex>().WithOptions(o => o.SetCacheable(true)), ec => ec.Count(), r => count = r);
113+
114+
await (batch.ExecuteAsync(CancellationToken.None));
115+
116+
Assert.That(results, Is.Not.Null);
117+
Assert.That(count, Is.GreaterThan(0));
118+
Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(0), "Query is expected to be retrieved from cache");
119+
}
120+
}
121+
122+
#region Test Setup
123+
124+
protected override HbmMapping GetMappings()
125+
{
126+
var mapper = new ModelMapper();
127+
mapper.Class<EntityComplex>(
128+
rc =>
129+
{
130+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
131+
132+
rc.Version(ep => ep.Version, vm => { });
133+
134+
rc.Property(x => x.Name);
135+
136+
rc.Property(ep => ep.LazyProp, m => m.Lazy(true));
137+
138+
rc.ManyToOne(ep => ep.Child1, m => m.Column("Child1Id"));
139+
rc.ManyToOne(ep => ep.Child2, m => m.Column("Child2Id"));
140+
rc.ManyToOne(ep => ep.SameTypeChild, m => m.Column("SameTypeChildId"));
141+
142+
rc.Bag(
143+
ep => ep.ChildrenList,
144+
m =>
145+
{
146+
m.Cascade(Mapping.ByCode.Cascade.All);
147+
m.Inverse(true);
148+
},
149+
a => a.OneToMany());
150+
});
151+
152+
mapper.Class<EntitySimpleChild>(
153+
rc =>
154+
{
155+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
156+
rc.ManyToOne(x => x.Parent);
157+
rc.Property(x => x.Name);
158+
});
159+
mapper.Class<EntityEager>(
160+
rc =>
161+
{
162+
rc.Lazy(false);
163+
164+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
165+
rc.Property(x => x.Name);
166+
167+
rc.Bag(ep => ep.ChildrenListSubselect,
168+
m =>
169+
{
170+
m.Cascade(Mapping.ByCode.Cascade.All);
171+
m.Inverse(true);
172+
m.Fetch(CollectionFetchMode.Subselect);
173+
m.Lazy(CollectionLazy.NoLazy);
174+
},
175+
a => a.OneToMany());
176+
177+
rc.Bag(ep => ep.ChildrenListEager,
178+
m =>
179+
{
180+
m.Lazy(CollectionLazy.NoLazy);
181+
},
182+
a => a.OneToMany());
183+
});
184+
mapper.Class<EntitySubselectChild>(
185+
rc =>
186+
{
187+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
188+
rc.Property(x => x.Name);
189+
rc.ManyToOne(c => c.Parent);
190+
});
191+
192+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
193+
}
194+
195+
protected override void OnTearDown()
196+
{
197+
using (ISession session = OpenSession())
198+
using (ITransaction transaction = session.BeginTransaction())
199+
{
200+
session.Delete("from System.Object");
201+
202+
session.Flush();
203+
transaction.Commit();
204+
}
205+
}
206+
207+
protected override void OnSetUp()
208+
{
209+
using (var session = OpenSession())
210+
using (var transaction = session.BeginTransaction())
211+
{
212+
var child1 = new EntitySimpleChild
213+
{
214+
Name = "Child1",
215+
};
216+
var child2 = new EntitySimpleChild
217+
{
218+
Name = "Child2"
219+
};
220+
var complex = new EntityComplex
221+
{
222+
Name = "ComplexEnityParent",
223+
Child1 = child1,
224+
Child2 = child2,
225+
LazyProp = "SomeBigValue",
226+
SameTypeChild = new EntityComplex()
227+
{
228+
Name = "ComplexEntityChild"
229+
},
230+
};
231+
child1.Parent = child2.Parent = complex;
232+
233+
var eager = new EntityEager()
234+
{
235+
Name = "eager1",
236+
};
237+
238+
var eager2 = new EntityEager()
239+
{
240+
Name = "eager2",
241+
};
242+
eager.ChildrenListSubselect = new List<EntitySubselectChild>()
243+
{
244+
new EntitySubselectChild()
245+
{
246+
Name = "subselect1",
247+
Parent = eager,
248+
},
249+
new EntitySubselectChild()
250+
{
251+
Name = "subselect2",
252+
Parent = eager,
253+
},
254+
};
255+
256+
session.Save(child1);
257+
session.Save(child2);
258+
session.Save(complex.SameTypeChild);
259+
session.Save(complex);
260+
session.Save(eager);
261+
session.Save(eager2);
262+
263+
session.Flush();
264+
transaction.Commit();
265+
266+
_parentId = complex.Id;
267+
}
268+
}
269+
270+
public class ListTransformerToInt : IResultTransformer
271+
{
272+
public object TransformTuple(object[] tuple, string[] aliases)
273+
{
274+
return tuple.Length == 1 ? tuple[0] : tuple;
275+
}
276+
277+
public IList TransformList(IList collection)
278+
{
279+
return new List<int>()
280+
{
281+
1,
282+
2,
283+
3,
284+
4,
285+
};
286+
}
287+
}
288+
289+
private bool SupportsMultipleQueries => Sfi.ConnectionProvider.Driver.SupportsMultipleQueries;
290+
291+
#endregion Test Setup
292+
}
293+
}

0 commit comments

Comments
 (0)