Skip to content

Commit 0481f87

Browse files
committed
Universal multi query
1 parent 2345bb4 commit 0481f87

25 files changed

+2138
-78
lines changed
Lines changed: 347 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,347 @@
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.Transform;
19+
using NUnit.Framework;
20+
using NHibernate.Criterion;
21+
22+
namespace NHibernate.Test.Futures
23+
{
24+
using System.Threading.Tasks;
25+
[TestFixture]
26+
public class MultiAnyQuerytBatchFixtureAsync : TestCaseMappingByCode
27+
{
28+
private Guid _parentId;
29+
private Guid _eagerId;
30+
31+
[Test]
32+
public async Task CanCombineCriteriaAndHqlInBatchAsync()
33+
{
34+
using (var session = OpenSession())
35+
{
36+
var batch = NewBatch(session);
37+
38+
var futureBatch1 =
39+
batch.AddAsList<int>(
40+
session.QueryOver<EntityComplex>()
41+
.Where(x => x.Version >= 0)
42+
.TransformUsing(new ListTransformerToInt()));
43+
44+
var futureEntComplList = batch.AddAsList(session.QueryOver<EntityComplex>().Where(x => x.Version >= 1));
45+
46+
var futureList3 = batch.AddAsList(session.Query<EntityComplex>().Where(ec => ec.Version > 2));
47+
48+
using (var sqlLog = new SqlLogSpy())
49+
{
50+
IList<int> list1 = await (futureBatch1.GetValueAsync());
51+
IList<EntityComplex> list2 = await (futureEntComplList.GetValueAsync());
52+
IList<EntityComplex> list3 = await (futureList3.GetValueAsync());
53+
if (SupportsMultipleQueries)
54+
Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(1));
55+
}
56+
}
57+
}
58+
59+
[Test]
60+
public async Task CanFetchCollectionInBatchAsync()
61+
{
62+
using (var sqlLog = new SqlLogSpy())
63+
using (var session = OpenSession())
64+
{
65+
var batch = NewBatch(session);
66+
67+
var q1 = session.QueryOver<EntityComplex>()
68+
.Where(x => x.Version >= 0);
69+
70+
batch.Add(new MultiAnyCriteriaQuery<object>(q1.RootCriteria));
71+
72+
batch.Add(new MultiAnyLinqQuery<EntityComplex>(session.Query<EntityComplex>().Fetch(c => c.ChildrenList)));
73+
await (batch.ExecuteAsync());
74+
var parent = await (session.LoadAsync<EntityComplex>(_parentId));
75+
Assert.That(NHibernateUtil.IsInitialized(parent), Is.True);
76+
Assert.That(NHibernateUtil.IsInitialized(parent.ChildrenList), Is.True);
77+
if (SupportsMultipleQueries)
78+
Assert.That(sqlLog.Appender.GetEvents().Length, Is.EqualTo(1));
79+
}
80+
}
81+
82+
#region Temp tests for debugging
83+
84+
[Test, Explicit]
85+
public async Task DebugInternalsAsync()
86+
{
87+
using (var sqlLog = new SqlLogSpy())
88+
using (var session = OpenSession())
89+
{
90+
var results = await (session.QueryOver<EntityComplex>()
91+
.TransformUsing(new ListTransformerToInt())
92+
.Cacheable()
93+
.ListAsync<int>());
94+
95+
var results2 = await (session.QueryOver<EntityComplex>()
96+
.TransformUsing(new ListTransformerToInt())
97+
.Cacheable()
98+
.ListAsync<int>());
99+
100+
var results3 = await (session.QueryOver<EntitySimpleChild>()
101+
.ListAsync<int>());
102+
}
103+
}
104+
105+
[Test, Explicit]
106+
public async Task TestQueryWithSubselectListAsync()
107+
{
108+
using (var sqlLog = new SqlLogSpy())
109+
using (var session = OpenSession())
110+
{
111+
var ec = await (session.QueryOver<EntityEager>().ListAsync());
112+
var eager = await (session.LoadAsync<EntityEager>(_eagerId));
113+
Assert.That(NHibernateUtil.IsInitialized(eager), Is.True);
114+
Assert.That(NHibernateUtil.IsInitialized(eager.ChildrenListSubselect), Is.True);
115+
}
116+
}
117+
118+
[Test, Explicit]
119+
public async Task TestQueryWithSubselectListFutureAsync()
120+
{
121+
using (var sqlLog = new SqlLogSpy())
122+
using (var session = OpenSession())
123+
{
124+
var ec = session.QueryOver<EntityEager>().Future();
125+
var eager = (await (ec.GetEnumerableAsync())).First();
126+
eager = await (session.LoadAsync<EntityEager>(_eagerId));
127+
Assert.That(NHibernateUtil.IsInitialized(eager), Is.True);
128+
await (NHibernateUtil.InitializeAsync(eager.ChildrenListSubselect));
129+
Assert.That(NHibernateUtil.IsInitialized(eager.ChildrenListSubselect), Is.True);
130+
}
131+
}
132+
133+
[Test, Explicit]
134+
public async Task FutureValueWithLinqSelectorAsync()
135+
{
136+
using (var session = OpenSession())
137+
{
138+
var b = NewBatch(session);
139+
var pq = session
140+
.Query<EntitySimpleChild>()
141+
//.Where(x => x.Id == _parentId)
142+
;
143+
//var r = pq.SingleOrDefault();
144+
var futureValue = b.AddAsValue(pq, c => c.SingleOrDefault());
145+
var value = await (futureValue.GetValueAsync());
146+
147+
}
148+
}
149+
150+
[Test, Explicit]
151+
public async Task TestMultiWithSubselectAsync()
152+
{
153+
using (var sqlLog = new SqlLogSpy())
154+
using (var session = OpenSession())
155+
{
156+
var batch = NewBatch(session);
157+
var eagerEntity = batch.AddAsList(session.QueryOver<EntityEager>());
158+
159+
var list = await (eagerEntity.GetValueAsync());
160+
var eager = await (session.LoadAsync<EntityEager>(_eagerId));
161+
Assert.That(NHibernateUtil.IsInitialized(eager), Is.True);
162+
Assert.That(NHibernateUtil.IsInitialized(eager.ChildrenListSubselect), Is.True);
163+
}
164+
}
165+
166+
#endregion Temp tests for debugging
167+
168+
#region Test Setup
169+
170+
protected override HbmMapping GetMappings()
171+
{
172+
var mapper = new ModelMapper();
173+
mapper.Class<EntityComplex>(
174+
rc =>
175+
{
176+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
177+
178+
rc.Version(ep => ep.Version, vm => { });
179+
180+
rc.Property(x => x.Name);
181+
182+
rc.Property(ep => ep.LazyProp, m => m.Lazy(true));
183+
184+
rc.ManyToOne(ep => ep.Child1, m => m.Column("Child1Id"));
185+
rc.ManyToOne(ep => ep.Child2, m => m.Column("Child2Id"));
186+
rc.ManyToOne(ep => ep.SameTypeChild, m => m.Column("SameTypeChildId"));
187+
188+
rc.Bag(
189+
ep => ep.ChildrenList,
190+
m =>
191+
{
192+
m.Cascade(Mapping.ByCode.Cascade.All);
193+
m.Inverse(true);
194+
},
195+
a => a.OneToMany());
196+
});
197+
198+
mapper.Class<EntitySimpleChild>(
199+
rc =>
200+
{
201+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
202+
rc.ManyToOne(x => x.Parent);
203+
rc.Property(x => x.Name);
204+
});
205+
mapper.Class<EntityEager>(
206+
rc =>
207+
{
208+
rc.Lazy(false);
209+
210+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
211+
rc.Property(x => x.Name);
212+
213+
rc.Bag(ep => ep.ChildrenListSubselect,
214+
m =>
215+
{
216+
m.Cascade(Mapping.ByCode.Cascade.All);
217+
m.Inverse(true);
218+
m.Fetch(CollectionFetchMode.Subselect);
219+
m.Lazy(CollectionLazy.NoLazy);
220+
},
221+
a => a.OneToMany());
222+
223+
rc.Bag(ep => ep.ChildrenListEager,
224+
m =>
225+
{
226+
m.Lazy(CollectionLazy.NoLazy);
227+
},
228+
a => a.OneToMany());
229+
});
230+
mapper.Class<EntitySubselectChild>(
231+
rc =>
232+
{
233+
rc.Id(x => x.Id, m => m.Generator(Generators.GuidComb));
234+
rc.Property(x => x.Name);
235+
rc.ManyToOne(c => c.Parent);
236+
});
237+
238+
return mapper.CompileMappingForAllExplicitlyAddedEntities();
239+
}
240+
241+
protected override void OnTearDown()
242+
{
243+
using (ISession session = OpenSession())
244+
using (ITransaction transaction = session.BeginTransaction())
245+
{
246+
session.Delete("from System.Object");
247+
248+
session.Flush();
249+
transaction.Commit();
250+
}
251+
}
252+
253+
protected override void OnSetUp()
254+
{
255+
using (var session = OpenSession())
256+
using (var transaction = session.BeginTransaction())
257+
{
258+
var child1 = new EntitySimpleChild
259+
{
260+
Name = "Child1",
261+
};
262+
var child2 = new EntitySimpleChild
263+
{
264+
Name = "Child2"
265+
};
266+
var complex = new EntityComplex
267+
{
268+
Name = "ComplexEnityParent",
269+
Child1 = child1,
270+
Child2 = child2,
271+
LazyProp = "SomeBigValue",
272+
SameTypeChild = new EntityComplex()
273+
{
274+
Name = "ComplexEntityChild"
275+
},
276+
};
277+
child1.Parent = child2.Parent = complex;
278+
279+
var eager = new EntityEager()
280+
{
281+
Name = "eager1",
282+
};
283+
284+
var eager2 = new EntityEager()
285+
{
286+
Name = "eager2",
287+
};
288+
eager.ChildrenListSubselect = new List<EntitySubselectChild>()
289+
{
290+
new EntitySubselectChild()
291+
{
292+
Name = "subselect1",
293+
Parent = eager,
294+
},
295+
new EntitySubselectChild()
296+
{
297+
Name = "subselect2",
298+
Parent = eager,
299+
},
300+
};
301+
302+
session.Save(child1);
303+
session.Save(child2);
304+
session.Save(complex.SameTypeChild);
305+
session.Save(complex);
306+
session.Save(eager);
307+
session.Save(eager2);
308+
309+
session.Flush();
310+
transaction.Commit();
311+
312+
_parentId = complex.Id;
313+
_eagerId = eager.Id;
314+
}
315+
}
316+
317+
private static MultiAnyQueryBatch NewBatch(ISession session)
318+
{
319+
var si = session.GetSessionImplementation();
320+
var batch = new MultiAnyQueryBatch(si);
321+
return batch;
322+
}
323+
324+
public class ListTransformerToInt : IResultTransformer
325+
{
326+
public object TransformTuple(object[] tuple, string[] aliases)
327+
{
328+
return tuple.Length == 1 ? tuple[0] : tuple;
329+
}
330+
331+
public IList TransformList(IList collection)
332+
{
333+
return new List<int>()
334+
{
335+
1,
336+
2,
337+
3,
338+
4,
339+
};
340+
}
341+
}
342+
343+
private bool SupportsMultipleQueries => Sfi.ConnectionProvider.Driver.SupportsMultipleQueries;
344+
345+
#endregion Test Setup
346+
}
347+
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
using System;
2+
using System.Collections.Generic;
3+
4+
namespace NHibernate.Test.Futures
5+
{
6+
public class EntityComplex
7+
{
8+
public virtual Guid Id { get; set; }
9+
10+
public virtual int Version { get; set; }
11+
12+
public virtual string Name { get; set; }
13+
14+
public virtual string LazyProp { get; set; }
15+
16+
public virtual EntitySimpleChild Child1 { get; set; }
17+
public virtual EntitySimpleChild Child2 { get; set; }
18+
public virtual EntityComplex SameTypeChild { get; set; }
19+
20+
public virtual IList<EntitySimpleChild> ChildrenList { get; set; } = new List<EntitySimpleChild>();
21+
public virtual IList<EntityComplex> ChildrenListEmpty { get; set; } = new List<EntityComplex>();
22+
23+
}
24+
25+
public class EntitySimpleChild
26+
{
27+
public virtual Guid Id { get; set; }
28+
public virtual string Name { get; set; }
29+
public virtual EntityComplex Parent { get; set; }
30+
}
31+
32+
public class EntitySubselectChild
33+
{
34+
public virtual Guid Id { get; set; }
35+
public virtual string Name { get; set; }
36+
public virtual EntityEager Parent { get; set; }
37+
}
38+
39+
public class EntityEager
40+
{
41+
public Guid Id { get; set; }
42+
public string Name { get; set; }
43+
44+
public IList<EntitySubselectChild> ChildrenListSubselect { get; set; }
45+
public IList<EntitySimpleChild> ChildrenListEager { get; set; } //= new HashSet<EntitySimpleChild>();
46+
}
47+
}

0 commit comments

Comments
 (0)