Skip to content

Commit d99a382

Browse files
authored
Refactored session List<T> method for Criteria (#1627)
1 parent d4e3a54 commit d99a382

File tree

13 files changed

+147
-75
lines changed

13 files changed

+147
-75
lines changed

src/NHibernate.Test/Async/Criteria/DetachedCriteriaSerializable.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -137,13 +137,16 @@ public async Task ExecutableCriteriaAsync()
137137
await (SerializeAndListAsync(dc));
138138

139139
// Subquery
140-
dc = DetachedCriteria.For(typeof(Student))
141-
.Add(Property.ForName("StudentNumber").Eq(232L))
142-
.SetProjection(Property.ForName("Name"));
140+
if (TestDialect.SupportsOperatorAll)
141+
{
142+
dc = DetachedCriteria.For(typeof(Student))
143+
.Add(Property.ForName("StudentNumber").Eq(232L))
144+
.SetProjection(Property.ForName("Name"));
143145

144-
DetachedCriteria dcs = DetachedCriteria.For(typeof(Student))
145-
.Add(Subqueries.PropertyEqAll("Name", dc));
146-
await (SerializeAndListAsync(dc));
146+
DetachedCriteria dcs = DetachedCriteria.For(typeof(Student))
147+
.Add(Subqueries.PropertyEqAll("Name", dc));
148+
await (SerializeAndListAsync(dcs));
149+
}
147150

148151
// SQLCriterion
149152
dc = DetachedCriteria.For(typeof(Student))

src/NHibernate.Test/Criteria/DetachedCriteriaSerializable.cs

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -391,13 +391,16 @@ public void ExecutableCriteria()
391391
SerializeAndList(dc);
392392

393393
// Subquery
394-
dc = DetachedCriteria.For(typeof(Student))
395-
.Add(Property.ForName("StudentNumber").Eq(232L))
396-
.SetProjection(Property.ForName("Name"));
394+
if (TestDialect.SupportsOperatorAll)
395+
{
396+
dc = DetachedCriteria.For(typeof(Student))
397+
.Add(Property.ForName("StudentNumber").Eq(232L))
398+
.SetProjection(Property.ForName("Name"));
397399

398-
DetachedCriteria dcs = DetachedCriteria.For(typeof(Student))
399-
.Add(Subqueries.PropertyEqAll("Name", dc));
400-
SerializeAndList(dc);
400+
DetachedCriteria dcs = DetachedCriteria.For(typeof(Student))
401+
.Add(Subqueries.PropertyEqAll("Name", dc));
402+
SerializeAndList(dcs);
403+
}
401404

402405
// SQLCriterion
403406
dc = DetachedCriteria.For(typeof(Student))

src/NHibernate/Async/Impl/AbstractSessionImpl.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
using NHibernate.Persister.Entity;
3131
using NHibernate.Transaction;
3232
using NHibernate.Type;
33+
using NHibernate.Util;
3334

3435
namespace NHibernate.Impl
3536
{
@@ -68,6 +69,7 @@ public virtual async Task<IList<T>> ListAsync<T>(IQueryExpression query, QueryPa
6869
}
6970
}
7071

72+
//TODO 6.0: Make abstract
7173
public virtual async Task<IList<T>> ListAsync<T>(CriteriaImpl criteria, CancellationToken cancellationToken)
7274
{
7375
cancellationToken.ThrowIfCancellationRequested();
@@ -79,17 +81,16 @@ public virtual async Task<IList<T>> ListAsync<T>(CriteriaImpl criteria, Cancella
7981
}
8082
}
8183

84+
//TODO 6.0: Make virtual
8285
public abstract Task ListAsync(CriteriaImpl criteria, IList results, CancellationToken cancellationToken);
86+
//{
87+
// ArrayHelper.AddAll(results, List(criteria));
88+
//}
8389

8490
public virtual async Task<IList> ListAsync(CriteriaImpl criteria, CancellationToken cancellationToken)
8591
{
8692
cancellationToken.ThrowIfCancellationRequested();
87-
using (BeginProcess())
88-
{
89-
var results = new List<object>();
90-
await (ListAsync(criteria, results, cancellationToken)).ConfigureAwait(false);
91-
return results;
92-
}
93+
return (await (ListAsync<object>(criteria, cancellationToken)).ConfigureAwait(false)).ToIList();
9394
}
9495

9596
public abstract Task<IList> ListFilterAsync(object collection, string filter, QueryParameters parameters, CancellationToken cancellationToken);

src/NHibernate/Async/Impl/CriteriaImpl.cs

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -29,33 +29,29 @@ public partial class CriteriaImpl : ICriteria, ISupportEntityJoinCriteria, ISupp
2929
public async Task<IList> ListAsync(CancellationToken cancellationToken = default(CancellationToken))
3030
{
3131
cancellationToken.ThrowIfCancellationRequested();
32-
var results = new List<object>();
33-
await (ListAsync(results, cancellationToken)).ConfigureAwait(false);
34-
return results;
32+
return (await (ListAsync<object>(cancellationToken)).ConfigureAwait(false)).ToIList();
3533
}
3634

3735
public async Task ListAsync(IList results, CancellationToken cancellationToken = default(CancellationToken))
36+
{
37+
cancellationToken.ThrowIfCancellationRequested();
38+
ArrayHelper.AddAll(results, await (ListAsync(cancellationToken)).ConfigureAwait(false));
39+
}
40+
41+
public async Task<IList<T>> ListAsync<T>(CancellationToken cancellationToken = default(CancellationToken))
3842
{
3943
cancellationToken.ThrowIfCancellationRequested();
4044
Before();
4145
try
4246
{
43-
await (session.ListAsync(this, results, cancellationToken)).ConfigureAwait(false);
47+
return await (session.ListAsync<T>(this, cancellationToken)).ConfigureAwait(false);
4448
}
4549
finally
4650
{
4751
After();
4852
}
4953
}
5054

51-
public async Task<IList<T>> ListAsync<T>(CancellationToken cancellationToken = default(CancellationToken))
52-
{
53-
cancellationToken.ThrowIfCancellationRequested();
54-
List<T> results = new List<T>();
55-
await (ListAsync(results, cancellationToken)).ConfigureAwait(false);
56-
return results;
57-
}
58-
5955
public async Task<T> UniqueResultAsync<T>(CancellationToken cancellationToken = default(CancellationToken))
6056
{
6157
cancellationToken.ThrowIfCancellationRequested();

src/NHibernate/Async/Impl/SessionImpl.cs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1121,7 +1121,7 @@ public override async Task<IEnumerable<T>> EnumerableFilterAsync<T>(object colle
11211121
}
11221122
}
11231123

1124-
public override async Task ListAsync(CriteriaImpl criteria, IList results, CancellationToken cancellationToken)
1124+
public override async Task<IList<T>> ListAsync<T>(CriteriaImpl criteria, CancellationToken cancellationToken)
11251125
{
11261126
cancellationToken.ThrowIfCancellationRequested();
11271127
using (BeginProcess())
@@ -1134,15 +1134,16 @@ public override async Task ListAsync(CriteriaImpl criteria, IList results, Cance
11341134

11351135
for (int i = 0; i < size; i++)
11361136
{
1137-
loaders[i] = new CriteriaLoader(
1137+
var loader = new CriteriaLoader(
11381138
GetOuterJoinLoadable(implementors[i]),
11391139
Factory,
11401140
criteria,
11411141
implementors[i],
11421142
enabledFilters
11431143
);
11441144

1145-
spaces.UnionWith(loaders[i].QuerySpaces);
1145+
spaces.UnionWith(loader.QuerySpaces);
1146+
loaders[size - 1 - i] = loader;
11461147
}
11471148

11481149
await (AutoFlushIfRequiredAsync(spaces, cancellationToken)).ConfigureAwait(false);
@@ -1152,11 +1153,9 @@ public override async Task ListAsync(CriteriaImpl criteria, IList results, Cance
11521153
{
11531154
try
11541155
{
1155-
for (int i = size - 1; i >= 0; i--)
1156-
{
1157-
ArrayHelper.AddAll(results, await (loaders[i].ListAsync(this, cancellationToken)).ConfigureAwait(false));
1158-
}
1156+
var results = await (loaders.LoadAllToListAsync<T>(this, cancellationToken)).ConfigureAwait(false);
11591157
success = true;
1158+
return results;
11601159
}
11611160
catch (OperationCanceledException) { throw; }
11621161
catch (HibernateException)
@@ -1176,6 +1175,13 @@ public override async Task ListAsync(CriteriaImpl criteria, IList results, Cance
11761175
}
11771176
}
11781177

1178+
//TODO 6.0: Remove (use base class implementation)
1179+
public override async Task ListAsync(CriteriaImpl criteria, IList results, CancellationToken cancellationToken)
1180+
{
1181+
cancellationToken.ThrowIfCancellationRequested();
1182+
ArrayHelper.AddAll(results, await (ListAsync(criteria, cancellationToken)).ConfigureAwait(false));
1183+
}
1184+
11791185
/// <summary>
11801186
/// remove any hard references to the entity that are held by the infrastructure
11811187
/// (references held by application or other persistant instances are okay)

src/NHibernate/Async/Impl/StatelessSessionImpl.cs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ public override async Task ListAsync(IQueryExpression queryExpression, QueryPara
122122
}
123123
}
124124

125-
public override async Task ListAsync(CriteriaImpl criteria, IList results, CancellationToken cancellationToken)
125+
public override async Task<IList<T>> ListAsync<T>(CriteriaImpl criteria, CancellationToken cancellationToken)
126126
{
127127
cancellationToken.ThrowIfCancellationRequested();
128128
using (BeginProcess())
@@ -133,18 +133,16 @@ public override async Task ListAsync(CriteriaImpl criteria, IList results, Cance
133133
CriteriaLoader[] loaders = new CriteriaLoader[size];
134134
for (int i = 0; i < size; i++)
135135
{
136-
loaders[i] = new CriteriaLoader(GetOuterJoinLoadable(implementors[i]), Factory,
136+
loaders[size - 1 - i] = new CriteriaLoader(GetOuterJoinLoadable(implementors[i]), Factory,
137137
criteria, implementors[i], EnabledFilters);
138138
}
139139

140140
bool success = false;
141141
try
142142
{
143-
for (int i = size - 1; i >= 0; i--)
144-
{
145-
ArrayHelper.AddAll(results, await (loaders[i].ListAsync(this, cancellationToken)).ConfigureAwait(false));
146-
}
143+
var results = await (loaders.LoadAllToListAsync<T>(this, cancellationToken)).ConfigureAwait(false);
147144
success = true;
145+
return results;
148146
}
149147
catch (OperationCanceledException) { throw; }
150148
catch (HibernateException)
@@ -159,11 +157,18 @@ public override async Task ListAsync(CriteriaImpl criteria, IList results, Cance
159157
finally
160158
{
161159
await (AfterOperationAsync(success, cancellationToken)).ConfigureAwait(false);
160+
temporaryPersistenceContext.Clear();
162161
}
163-
temporaryPersistenceContext.Clear();
164162
}
165163
}
166164

165+
//TODO 6.0: Remove (use base class implementation)
166+
public override async Task ListAsync(CriteriaImpl criteria, IList results, CancellationToken cancellationToken)
167+
{
168+
cancellationToken.ThrowIfCancellationRequested();
169+
ArrayHelper.AddAll(results, await (ListAsync(criteria, cancellationToken)).ConfigureAwait(false));
170+
}
171+
167172
public override Task<IEnumerable> EnumerableAsync(IQueryExpression queryExpression, QueryParameters queryParameters, CancellationToken cancellationToken)
168173
{
169174
throw new NotImplementedException();

src/NHibernate/Async/Loader/Criteria/CriteriaLoader.cs

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
using System.Collections;
1212
using System.Collections.Generic;
1313
using System.Data.Common;
14+
using System.Linq;
1415
using NHibernate.Engine;
1516
using NHibernate.Impl;
1617
using NHibernate.Param;
@@ -24,6 +25,29 @@ namespace NHibernate.Loader.Criteria
2425
{
2526
using System.Threading.Tasks;
2627
using System.Threading;
28+
internal static partial class CriteriaLoaderExtensions
29+
{
30+
/// <summary>
31+
/// Loads all loaders results to single typed list
32+
/// </summary>
33+
internal static async Task<List<T>> LoadAllToListAsync<T>(this IList<CriteriaLoader> loaders, ISessionImplementor session, CancellationToken cancellationToken)
34+
{
35+
cancellationToken.ThrowIfCancellationRequested();
36+
var subresults = new List<IList>(loaders.Count);
37+
foreach(var l in loaders)
38+
{
39+
subresults.Add(await (l.ListAsync(session, cancellationToken)).ConfigureAwait(false));
40+
}
41+
42+
var results = new List<T>(subresults.Sum(r => r.Count));
43+
foreach(var list in subresults)
44+
{
45+
ArrayHelper.AddAll(results, list);
46+
}
47+
return results;
48+
}
49+
}
50+
2751
public partial class CriteriaLoader : OuterJoinLoader
2852
{
2953

src/NHibernate/Impl/AbstractSessionImpl.cs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
using NHibernate.Persister.Entity;
2121
using NHibernate.Transaction;
2222
using NHibernate.Type;
23+
using NHibernate.Util;
2324

2425
namespace NHibernate.Impl
2526
{
@@ -149,6 +150,7 @@ public virtual IList<T> List<T>(IQueryExpression query, QueryParameters paramete
149150
}
150151
}
151152

153+
//TODO 6.0: Make abstract
152154
public virtual IList<T> List<T>(CriteriaImpl criteria)
153155
{
154156
using (BeginProcess())
@@ -159,16 +161,15 @@ public virtual IList<T> List<T>(CriteriaImpl criteria)
159161
}
160162
}
161163

164+
//TODO 6.0: Make virtual
162165
public abstract void List(CriteriaImpl criteria, IList results);
166+
//{
167+
// ArrayHelper.AddAll(results, List(criteria));
168+
//}
163169

164170
public virtual IList List(CriteriaImpl criteria)
165171
{
166-
using (BeginProcess())
167-
{
168-
var results = new List<object>();
169-
List(criteria, results);
170-
return results;
171-
}
172+
return List<object>(criteria).ToIList();
172173
}
173174

174175
public abstract IList ListFilter(object collection, string filter, QueryParameters parameters);

src/NHibernate/Impl/CriteriaImpl.cs

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -280,31 +280,27 @@ public ICriteria Add(ICriterion expression)
280280

281281
public IList List()
282282
{
283-
var results = new List<object>();
284-
List(results);
285-
return results;
283+
return List<object>().ToIList();
286284
}
287285

288286
public void List(IList results)
287+
{
288+
ArrayHelper.AddAll(results, List());
289+
}
290+
291+
public IList<T> List<T>()
289292
{
290293
Before();
291294
try
292295
{
293-
session.List(this, results);
296+
return session.List<T>(this);
294297
}
295298
finally
296299
{
297300
After();
298301
}
299302
}
300303

301-
public IList<T> List<T>()
302-
{
303-
List<T> results = new List<T>();
304-
List(results);
305-
return results;
306-
}
307-
308304
public T UniqueResult<T>()
309305
{
310306
object result = UniqueResult();

0 commit comments

Comments
 (0)