@@ -228,52 +228,42 @@ async Task<IList> FindAsync(string query, object[] values, IType[] types, Cancel
228
228
}
229
229
}
230
230
231
- public override async Task ListAsync ( IQueryExpression queryExpression , QueryParameters queryParameters , IList results , CancellationToken cancellationToken )
231
+ public override Task ListAsync ( IQueryExpression queryExpression , QueryParameters queryParameters , IList results , CancellationToken cancellationToken )
232
232
{
233
- cancellationToken . ThrowIfCancellationRequested ( ) ;
234
- using ( new SessionIdLoggingContext ( SessionId ) )
233
+ if ( cancellationToken . IsCancellationRequested )
235
234
{
236
- CheckAndUpdateSessionStatus ( ) ;
237
- queryParameters . ValidateParameters ( ) ;
238
- var plan = GetHQLQueryPlan ( queryExpression , false ) ;
239
-
240
- await ( AutoFlushIfRequiredAsync ( plan . QuerySpaces , cancellationToken ) ) . ConfigureAwait ( false ) ;
235
+ return Task . FromCanceled < object > ( cancellationToken ) ;
236
+ }
237
+ return ListAsync ( queryExpression , queryParameters , results , null , cancellationToken ) ;
238
+ }
241
239
242
- bool success = false ;
243
- using ( SuspendAutoFlush ( ) ) //stops flush being called multiple times if this method is recursively called
244
- {
245
- try
246
- {
247
- await ( plan . PerformListAsync ( queryParameters , this , results , cancellationToken ) ) . ConfigureAwait ( false ) ;
248
- success = true ;
249
- }
250
- catch ( HibernateException )
251
- {
252
- // Do not call Convert on HibernateExceptions
253
- throw ;
254
- }
255
- catch ( Exception e )
256
- {
257
- throw Convert ( e , "Could not execute query" ) ;
258
- }
259
- finally
260
- {
261
- await ( AfterOperationAsync ( success , cancellationToken ) ) . ConfigureAwait ( false ) ;
262
- }
263
- }
240
+ protected override Task ListFilterAsync ( object collection , IQueryExpression queryExpression , QueryParameters queryParameters , IList results , CancellationToken cancellationToken )
241
+ {
242
+ if ( collection == null )
243
+ throw new ArgumentNullException ( nameof ( collection ) ) ;
244
+ if ( cancellationToken . IsCancellationRequested )
245
+ {
246
+ return Task . FromCanceled < object > ( cancellationToken ) ;
264
247
}
248
+ return ListAsync ( queryExpression , queryParameters , results , collection , cancellationToken ) ;
265
249
}
266
250
267
- protected override async Task ListFilterAsync ( object collection , IQueryExpression queryExpression , QueryParameters queryParameters , IList results , CancellationToken cancellationToken )
251
+ private async Task ListAsync ( IQueryExpression queryExpression , QueryParameters queryParameters , IList results , object filterConnection , CancellationToken cancellationToken )
268
252
{
269
253
cancellationToken . ThrowIfCancellationRequested ( ) ;
270
254
using ( new SessionIdLoggingContext ( SessionId ) )
271
255
{
272
256
CheckAndUpdateSessionStatus ( ) ;
273
257
queryParameters . ValidateParameters ( ) ;
274
- var plan = await ( GetFilterQueryPlanAsync ( collection , queryExpression , queryParameters , false , cancellationToken ) ) . ConfigureAwait ( false ) ;
275
258
276
- await ( AutoFlushIfRequiredAsync ( plan . QuerySpaces , cancellationToken ) ) . ConfigureAwait ( false ) ;
259
+ var isFilter = filterConnection != null ;
260
+ var plan = isFilter
261
+ ? await ( GetFilterQueryPlanAsync ( filterConnection , queryExpression , queryParameters , false , cancellationToken ) ) . ConfigureAwait ( false )
262
+ : GetHQLQueryPlan ( queryExpression , false ) ;
263
+
264
+ // GetFilterQueryPlan has already auto flushed or fully flush.
265
+ if ( ! isFilter )
266
+ await ( AutoFlushIfRequiredAsync ( plan . QuerySpaces , cancellationToken ) ) . ConfigureAwait ( false ) ;
277
267
278
268
bool success = false ;
279
269
using ( SuspendAutoFlush ( ) ) //stops flush being called multiple times if this method is recursively called
@@ -441,73 +431,39 @@ public override async Task<IQuery> CreateFilterAsync(object collection, IQueryEx
441
431
}
442
432
}
443
433
444
- private async Task < IQueryExpressionPlan > GetFilterQueryPlanAsync ( object collection , IQueryExpression queryExpression , QueryParameters parameters , bool shallow , CancellationToken cancellationToken )
434
+ private Task < IQueryExpressionPlan > GetFilterQueryPlanAsync ( object collection , IQueryExpression queryExpression , QueryParameters parameters , bool shallow , CancellationToken cancellationToken )
445
435
{
446
- cancellationToken . ThrowIfCancellationRequested ( ) ;
447
- using ( new SessionIdLoggingContext ( SessionId ) )
436
+ if ( cancellationToken . IsCancellationRequested )
448
437
{
449
- CollectionEntry entry = persistenceContext . GetCollectionEntryOrNull ( collection ) ;
450
- ICollectionPersister roleBeforeFlush = ( entry == null ) ? null : entry . LoadedPersister ;
451
-
452
- IQueryExpressionPlan plan ;
453
- if ( roleBeforeFlush == null )
454
- {
455
- // if it was previously unreferenced, we need to flush in order to
456
- // get its state into the database in order to execute query
457
- await ( FlushAsync ( cancellationToken ) ) . ConfigureAwait ( false ) ;
458
- entry = persistenceContext . GetCollectionEntryOrNull ( collection ) ;
459
- ICollectionPersister roleAfterFlush = ( entry == null ) ? null : entry . LoadedPersister ;
460
- if ( roleAfterFlush == null )
461
- {
462
- throw new QueryException ( "The collection was unreferenced" ) ;
463
- }
464
- plan = Factory . QueryPlanCache . GetFilterQueryPlan ( queryExpression , roleAfterFlush . Role , shallow , EnabledFilters ) ;
465
- }
466
- else
467
- {
468
- // otherwise, we only need to flush if there are in-memory changes
469
- // to the queried tables
470
- plan = Factory . QueryPlanCache . GetFilterQueryPlan ( queryExpression , roleBeforeFlush . Role , shallow , EnabledFilters ) ;
471
-
472
- if ( await ( AutoFlushIfRequiredAsync ( plan . QuerySpaces , cancellationToken ) ) . ConfigureAwait ( false ) )
473
- {
474
- // might need to run a different filter entirely after the flush
475
- // because the collection role may have changed
476
- entry = persistenceContext . GetCollectionEntryOrNull ( collection ) ;
477
- ICollectionPersister roleAfterFlush = ( entry == null ) ? null : entry . LoadedPersister ;
478
- if ( roleBeforeFlush != roleAfterFlush )
479
- {
480
- if ( roleAfterFlush == null )
481
- {
482
- throw new QueryException ( "The collection was dereferenced" ) ;
483
- }
484
- plan = Factory . QueryPlanCache . GetFilterQueryPlan ( queryExpression , roleAfterFlush . Role , shallow , EnabledFilters ) ;
485
- }
486
- }
487
- }
488
-
489
- if ( parameters != null )
490
- {
491
- parameters . PositionalParameterValues [ 0 ] = entry . LoadedKey ;
492
- parameters . PositionalParameterTypes [ 0 ] = entry . LoadedPersister . KeyType ;
493
- }
438
+ return Task . FromCanceled < IQueryExpressionPlan > ( cancellationToken ) ;
439
+ }
440
+ return GetFilterQueryPlanAsync ( collection , parameters , shallow , null , queryExpression , cancellationToken ) ;
441
+ }
494
442
495
- return plan ;
443
+ private Task < IQueryExpressionPlan > GetFilterQueryPlanAsync ( object collection , string filter , QueryParameters parameters , bool shallow , CancellationToken cancellationToken )
444
+ {
445
+ if ( cancellationToken . IsCancellationRequested )
446
+ {
447
+ return Task . FromCanceled < IQueryExpressionPlan > ( cancellationToken ) ;
496
448
}
449
+ return GetFilterQueryPlanAsync ( collection , parameters , shallow , filter , null , cancellationToken ) ;
497
450
}
498
451
499
- private async Task < IQueryExpressionPlan > GetFilterQueryPlanAsync ( object collection , string filter , QueryParameters parameters , bool shallow , CancellationToken cancellationToken )
452
+ private async Task < IQueryExpressionPlan > GetFilterQueryPlanAsync ( object collection , QueryParameters parameters , bool shallow ,
453
+ string filter , IQueryExpression queryExpression , CancellationToken cancellationToken )
500
454
{
501
455
cancellationToken . ThrowIfCancellationRequested ( ) ;
502
456
using ( new SessionIdLoggingContext ( SessionId ) )
503
457
{
504
458
if ( collection == null )
505
- {
506
- throw new ArgumentNullException ( "collection" , "null collection passed to filter" ) ;
507
- }
459
+ throw new ArgumentNullException ( nameof ( collection ) , "null collection passed to filter" ) ;
460
+ if ( filter != null && queryExpression != null )
461
+ throw new ArgumentException ( $ "Either { nameof ( filter ) } or { nameof ( queryExpression ) } must be specified, not both.") ;
462
+ if ( filter == null && queryExpression == null )
463
+ throw new ArgumentException ( $ "{ nameof ( filter ) } and { nameof ( queryExpression ) } were both null.") ;
508
464
509
- CollectionEntry entry = persistenceContext . GetCollectionEntryOrNull ( collection ) ;
510
- ICollectionPersister roleBeforeFlush = ( entry == null ) ? null : entry . LoadedPersister ;
465
+ var entry = persistenceContext . GetCollectionEntryOrNull ( collection ) ;
466
+ var roleBeforeFlush = entry ? . LoadedPersister ;
511
467
512
468
IQueryExpressionPlan plan ;
513
469
if ( roleBeforeFlush == null )
@@ -516,31 +472,31 @@ private async Task<IQueryExpressionPlan> GetFilterQueryPlanAsync(object collecti
516
472
// get its state into the database in order to execute query
517
473
await ( FlushAsync ( cancellationToken ) ) . ConfigureAwait ( false ) ;
518
474
entry = persistenceContext . GetCollectionEntryOrNull ( collection ) ;
519
- ICollectionPersister roleAfterFlush = ( entry == null ) ? null : entry . LoadedPersister ;
475
+ var roleAfterFlush = entry ? . LoadedPersister ;
520
476
if ( roleAfterFlush == null )
521
477
{
522
478
throw new QueryException ( "The collection was unreferenced" ) ;
523
479
}
524
- plan = Factory . QueryPlanCache . GetFilterQueryPlan ( filter , roleAfterFlush . Role , shallow , EnabledFilters ) ;
480
+ plan = GetFilterQueryPlan ( roleAfterFlush . Role , shallow , filter , queryExpression ) ;
525
481
}
526
482
else
527
483
{
528
484
// otherwise, we only need to flush if there are in-memory changes
529
485
// to the queried tables
530
- plan = Factory . QueryPlanCache . GetFilterQueryPlan ( filter , roleBeforeFlush . Role , shallow , EnabledFilters ) ;
486
+ plan = GetFilterQueryPlan ( roleBeforeFlush . Role , shallow , filter , queryExpression ) ;
531
487
if ( await ( AutoFlushIfRequiredAsync ( plan . QuerySpaces , cancellationToken ) ) . ConfigureAwait ( false ) )
532
488
{
533
489
// might need to run a different filter entirely after the flush
534
490
// because the collection role may have changed
535
491
entry = persistenceContext . GetCollectionEntryOrNull ( collection ) ;
536
- ICollectionPersister roleAfterFlush = ( entry == null ) ? null : entry . LoadedPersister ;
492
+ var roleAfterFlush = entry ? . LoadedPersister ;
537
493
if ( roleBeforeFlush != roleAfterFlush )
538
494
{
539
495
if ( roleAfterFlush == null )
540
496
{
541
497
throw new QueryException ( "The collection was dereferenced" ) ;
542
498
}
543
- plan = Factory . QueryPlanCache . GetFilterQueryPlan ( filter , roleAfterFlush . Role , shallow , EnabledFilters ) ;
499
+ plan = GetFilterQueryPlan ( roleAfterFlush . Role , shallow , filter , queryExpression ) ;
544
500
}
545
501
}
546
502
}
0 commit comments