@@ -381,5 +381,231 @@ public async Task WhereAfterFetchAndSingleOrDefaultAsync()
381381
382382 Assert . IsTrue ( NHibernateUtil . IsInitialized ( order . Shipper ) ) ;
383383 }
384+
385+ [ Test ]
386+ public async Task WhereReuseJoinsAsync ( )
387+ {
388+ OrderLine orderLine ;
389+ using ( var logSpy = new SqlLogSpy ( ) )
390+ {
391+ orderLine = ( await ( db . OrderLines
392+ . Where ( o => o . Order . Customer . ContactName == "Maria Anders" )
393+ . Fetch ( o => o . Order ) . ThenFetch ( o => o . Customer )
394+ . ToListAsync ( ) ) )
395+ . First ( ) ;
396+
397+ var sql = logSpy . GetWholeLog ( ) ;
398+ Assert . That ( GetTotalOccurrences ( sql , "join" ) , Is . EqualTo ( 2 ) ) ;
399+ Assert . That ( GetTotalOccurrences ( sql , "inner join" ) , Is . EqualTo ( 2 ) ) ;
400+ Assert . That ( NHibernateUtil . IsInitialized ( orderLine . Order ) , Is . True ) ;
401+ Assert . That ( NHibernateUtil . IsInitialized ( orderLine . Order . Customer ) , Is . True ) ;
402+ }
403+
404+ session . Clear ( ) ;
405+ using ( var logSpy = new SqlLogSpy ( ) )
406+ {
407+ orderLine = ( await ( db . OrderLines
408+ . Where ( o => o . Order . Customer . ContactName == "Maria Anders" )
409+ . Fetch ( o => o . Order )
410+ . ToListAsync ( ) ) )
411+ . First ( ) ;
412+
413+ var sql = logSpy . GetWholeLog ( ) ;
414+ Assert . That ( GetTotalOccurrences ( sql , "join" ) , Is . EqualTo ( 2 ) ) ;
415+ Assert . That ( GetTotalOccurrences ( sql , "inner join" ) , Is . EqualTo ( 2 ) ) ;
416+ Assert . That ( NHibernateUtil . IsInitialized ( orderLine . Order ) , Is . True ) ;
417+ Assert . That ( NHibernateUtil . IsInitialized ( orderLine . Order . Customer ) , Is . False ) ;
418+ }
419+
420+ session . Clear ( ) ;
421+ using ( var logSpy = new SqlLogSpy ( ) )
422+ {
423+ orderLine = ( await ( db . OrderLines
424+ . Where ( o => o . Order . OrderLines . Any ( l => l . Product . Name == "Tofu" ) )
425+ . Fetch ( o => o . Order ) . ThenFetch ( o => o . Customer )
426+ . ToListAsync ( ) ) )
427+ . First ( ) ;
428+
429+ var sql = logSpy . GetWholeLog ( ) ;
430+ sql = sql . Substring ( 0 , sql . IndexOf ( "where" ) ) ;
431+ Assert . That ( GetTotalOccurrences ( sql , "join" ) , Is . EqualTo ( 2 ) ) ;
432+ Assert . That ( GetTotalOccurrences ( sql , "left outer join" ) , Is . EqualTo ( 2 ) ) ;
433+ Assert . That ( NHibernateUtil . IsInitialized ( orderLine . Order ) , Is . True ) ;
434+ Assert . That ( NHibernateUtil . IsInitialized ( orderLine . Order . Customer ) , Is . True ) ;
435+ }
436+
437+ using ( var logSpy = new SqlLogSpy ( ) )
438+ {
439+ ( await ( db . Employees
440+ . Where ( o => o . Superior . Superior . Superior . FirstName != null )
441+ . Fetch ( o => o . Superior )
442+ . ToListAsync ( ) ) )
443+ . FirstOrDefault ( ) ;
444+
445+ var sql = logSpy . GetWholeLog ( ) ;
446+ Assert . That ( GetTotalOccurrences ( sql , "," ) , Is . EqualTo ( 31 ) , "Only the first level should be fetched." ) ;
447+ Assert . That ( GetTotalOccurrences ( sql , "join" ) , Is . EqualTo ( 3 ) ) ;
448+ Assert . That ( GetTotalOccurrences ( sql , "inner join" ) , Is . EqualTo ( 3 ) ) ;
449+ }
450+
451+ using ( var logSpy = new SqlLogSpy ( ) )
452+ {
453+ ( await ( db . Employees
454+ . Where ( o => o . Superior . FirstName != null )
455+ . Fetch ( o => o . Superior ) . ThenFetch ( o => o . Superior ) . ThenFetch ( o => o . Superior )
456+ . ToListAsync ( ) ) )
457+ . FirstOrDefault ( ) ;
458+
459+ var sql = logSpy . GetWholeLog ( ) ;
460+ Assert . That ( GetTotalOccurrences ( sql , "join" ) , Is . EqualTo ( 3 ) ) ;
461+ Assert . That ( GetTotalOccurrences ( sql , "inner join" ) , Is . EqualTo ( 1 ) ) ;
462+ Assert . That ( GetTotalOccurrences ( sql , "left outer join" ) , Is . EqualTo ( 2 ) ) ;
463+ }
464+ }
465+
466+ [ Test ]
467+ public async Task OrderByReuseJoinsAsync ( )
468+ {
469+ OrderLine orderLine ;
470+ using ( var logSpy = new SqlLogSpy ( ) )
471+ {
472+ orderLine = ( await ( db . OrderLines
473+ . Where ( o => o . Order . OrderId == 10248 )
474+ . OrderBy ( o => o . Order . Customer . ContactName )
475+ . Fetch ( o => o . Order ) . ThenFetch ( o => o . Customer )
476+ . ToListAsync ( ) ) )
477+ . First ( ) ;
478+
479+ var sql = logSpy . GetWholeLog ( ) ;
480+ Assert . That ( GetTotalOccurrences ( sql , "join" ) , Is . EqualTo ( 2 ) ) ;
481+ Assert . That ( GetTotalOccurrences ( sql , "left outer join" ) , Is . EqualTo ( 2 ) ) ;
482+ Assert . That ( NHibernateUtil . IsInitialized ( orderLine . Order ) , Is . True ) ;
483+ Assert . That ( NHibernateUtil . IsInitialized ( orderLine . Order . Customer ) , Is . True ) ;
484+ }
485+
486+ session . Clear ( ) ;
487+ using ( var logSpy = new SqlLogSpy ( ) )
488+ {
489+ orderLine = ( await ( db . OrderLines
490+ . Where ( o => o . Order . OrderId == 10248 )
491+ . OrderBy ( o => o . Order . Customer . ContactName )
492+ . Fetch ( o => o . Order )
493+ . ToListAsync ( ) ) )
494+ . First ( ) ;
495+
496+ var sql = logSpy . GetWholeLog ( ) ;
497+ Assert . That ( GetTotalOccurrences ( sql , "join" ) , Is . EqualTo ( 2 ) ) ;
498+ Assert . That ( GetTotalOccurrences ( sql , "left outer join" ) , Is . EqualTo ( 2 ) ) ;
499+ Assert . That ( NHibernateUtil . IsInitialized ( orderLine . Order ) , Is . True ) ;
500+ Assert . That ( NHibernateUtil . IsInitialized ( orderLine . Order . Customer ) , Is . False ) ;
501+ }
502+
503+ using ( var logSpy = new SqlLogSpy ( ) )
504+ {
505+ ( await ( db . Employees
506+ . OrderBy ( o => o . Superior . Superior . Superior . FirstName )
507+ . Fetch ( o => o . Superior )
508+ . ToListAsync ( ) ) )
509+ . FirstOrDefault ( ) ;
510+
511+ var sql = logSpy . GetWholeLog ( ) ;
512+ Assert . That ( GetTotalOccurrences ( sql , "," ) , Is . EqualTo ( 31 ) , "Only the first level should be fetched." ) ;
513+ Assert . That ( GetTotalOccurrences ( sql , "join" ) , Is . EqualTo ( 3 ) ) ;
514+ Assert . That ( GetTotalOccurrences ( sql , "left outer join" ) , Is . EqualTo ( 3 ) ) ;
515+ }
516+
517+ using ( var logSpy = new SqlLogSpy ( ) )
518+ {
519+ ( await ( db . Employees
520+ . OrderBy ( o => o . Superior . FirstName )
521+ . Fetch ( o => o . Superior ) . ThenFetch ( o => o . Superior ) . ThenFetch ( o => o . Superior )
522+ . ToListAsync ( ) ) )
523+ . FirstOrDefault ( ) ;
524+
525+ var sql = logSpy . GetWholeLog ( ) ;
526+ Assert . That ( GetTotalOccurrences ( sql , "join" ) , Is . EqualTo ( 3 ) ) ;
527+ Assert . That ( GetTotalOccurrences ( sql , "left outer join" ) , Is . EqualTo ( 3 ) ) ;
528+ }
529+ }
530+
531+ [ Test ]
532+ public async Task WhereAndOrderByReuseJoinsAsync ( )
533+ {
534+ OrderLine orderLine ;
535+ using ( var logSpy = new SqlLogSpy ( ) )
536+ {
537+ orderLine = ( await ( db . OrderLines
538+ . Where ( o => o . Order . Customer . ContactName == "Maria Anders" )
539+ . OrderBy ( o => o . Order . Customer . ContactName )
540+ . Fetch ( o => o . Order ) . ThenFetch ( o => o . Customer )
541+ . ToListAsync ( ) ) )
542+ . First ( ) ;
543+
544+ var sql = logSpy . GetWholeLog ( ) ;
545+ Assert . That ( GetTotalOccurrences ( sql , "join" ) , Is . EqualTo ( 2 ) ) ;
546+ Assert . That ( GetTotalOccurrences ( sql , "inner join" ) , Is . EqualTo ( 2 ) ) ;
547+ Assert . That ( NHibernateUtil . IsInitialized ( orderLine . Order ) , Is . True ) ;
548+ Assert . That ( NHibernateUtil . IsInitialized ( orderLine . Order . Customer ) , Is . True ) ;
549+ }
550+
551+ session . Clear ( ) ;
552+ using ( var logSpy = new SqlLogSpy ( ) )
553+ {
554+ orderLine = ( await ( db . OrderLines
555+ . Where ( o => o . Order . Customer . ContactName == "Maria Anders" )
556+ . OrderBy ( o => o . Order . Customer . ContactName )
557+ . Fetch ( o => o . Order )
558+ . ToListAsync ( ) ) )
559+ . First ( ) ;
560+
561+ var sql = logSpy . GetWholeLog ( ) ;
562+ Assert . That ( GetTotalOccurrences ( sql , "join" ) , Is . EqualTo ( 2 ) ) ;
563+ Assert . That ( GetTotalOccurrences ( sql , "inner join" ) , Is . EqualTo ( 2 ) ) ;
564+ Assert . That ( NHibernateUtil . IsInitialized ( orderLine . Order ) , Is . True ) ;
565+ Assert . That ( NHibernateUtil . IsInitialized ( orderLine . Order . Customer ) , Is . False ) ;
566+ }
567+
568+ using ( var logSpy = new SqlLogSpy ( ) )
569+ {
570+ ( await ( db . Employees
571+ . Where ( o => o . Superior . Superior . Superior . FirstName != null )
572+ . OrderBy ( o => o . Superior . Superior . Superior . FirstName )
573+ . Fetch ( o => o . Superior )
574+ . ToListAsync ( ) ) )
575+ . FirstOrDefault ( ) ;
576+
577+ var sql = logSpy . GetWholeLog ( ) ;
578+ Assert . That ( GetTotalOccurrences ( sql , "," ) , Is . EqualTo ( 31 ) , "Only the first level should be fetched." ) ;
579+ Assert . That ( GetTotalOccurrences ( sql , "join" ) , Is . EqualTo ( 3 ) ) ;
580+ Assert . That ( GetTotalOccurrences ( sql , "inner join" ) , Is . EqualTo ( 3 ) ) ;
581+ }
582+
583+ using ( var logSpy = new SqlLogSpy ( ) )
584+ {
585+ ( await ( db . Employees
586+ . Where ( o => o . Superior . FirstName != null )
587+ . OrderBy ( o => o . Superior . FirstName )
588+ . Fetch ( o => o . Superior ) . ThenFetch ( o => o . Superior ) . ThenFetch ( o => o . Superior )
589+ . ToListAsync ( ) ) )
590+ . FirstOrDefault ( ) ;
591+
592+ var sql = logSpy . GetWholeLog ( ) ;
593+ Assert . That ( GetTotalOccurrences ( sql , "join" ) , Is . EqualTo ( 3 ) ) ;
594+ Assert . That ( GetTotalOccurrences ( sql , "inner join" ) , Is . EqualTo ( 1 ) ) ;
595+ Assert . That ( GetTotalOccurrences ( sql , "left outer join" ) , Is . EqualTo ( 2 ) ) ;
596+ }
597+ }
598+
599+ [ Test ]
600+ public async Task FetchBeforeSelectAsync ( )
601+ {
602+ var result = await ( db . Orders
603+ . Where ( o => o . OrderId == 10248 )
604+ . Fetch ( x => x . Customer )
605+ . Select ( x => new { x . Customer . ContactName } )
606+ . ToListAsync ( ) ) ;
607+
608+ Assert . True ( result . Any ( ) ) ;
609+ }
384610 }
385611}
0 commit comments