@@ -386,6 +386,197 @@ public async Task CanSelectNewGuidAsync()
386
386
Assert . Fail ( "The test should have thrown a QueryException, but has not thrown anything" ) ;
387
387
}
388
388
389
+ [ Test ]
390
+ public async Task CanQueryByRandomDoubleAsync ( )
391
+ {
392
+ using ( var spy = new SqlLogSpy ( ) )
393
+ {
394
+ var random = new Random ( ) ;
395
+ var x = await ( db . Orders . CountAsync ( o => o . OrderId > random . NextDouble ( ) ) ) ;
396
+
397
+ Assert . That ( x , Is . GreaterThan ( 0 ) ) ;
398
+ AssertFunctionInSql ( "random" , spy ) ;
399
+ }
400
+ }
401
+
402
+ [ Test ]
403
+ public async Task CanSelectRandomDoubleAsync ( )
404
+ {
405
+ using ( var spy = new SqlLogSpy ( ) )
406
+ {
407
+ var random = new Random ( ) ;
408
+ var x =
409
+ await ( db
410
+ . Orders . Select ( o => new { id = o . OrderId , r = random . NextDouble ( ) } )
411
+ . OrderBy ( o => o . id ) . ToListAsync ( ) ) ;
412
+
413
+ Assert . That ( x , Has . Count . GreaterThan ( 0 ) ) ;
414
+ var randomValues = x . Select ( o => o . r ) . Distinct ( ) . ToArray ( ) ;
415
+ Assert . That ( randomValues , Has . All . GreaterThanOrEqualTo ( 0 ) . And . LessThan ( 1 ) ) ;
416
+
417
+ if ( ! LegacyPreEvaluation && IsFunctionSupported ( "random" ) )
418
+ {
419
+ // Naïve randomness check
420
+ Assert . That (
421
+ randomValues ,
422
+ Has . Length . GreaterThan ( x . Count / 2 ) ,
423
+ "Generated values do not seem very random" ) ;
424
+ }
425
+
426
+ AssertFunctionInSql ( "random" , spy ) ;
427
+ }
428
+ }
429
+
430
+ [ Test ]
431
+ public async Task CanQueryByRandomIntAsync ( )
432
+ {
433
+ var idMin = await ( db . Orders . MinAsync ( o => o . OrderId ) ) ;
434
+ using ( var spy = new SqlLogSpy ( ) )
435
+ {
436
+ var random = new Random ( ) ;
437
+ // Dodge a Firebird driver limitation by putting the constants before the order id.
438
+ // This driver cast parameters to their types in some cases for avoiding Firebird complaining of not
439
+ // knowing the type of the condition. For some reasons the driver considers the casting should not be
440
+ // done next to the conditional operator. Having the cast only on one side is enough for avoiding
441
+ // Firebird complain, so moving the constants on the left side have been put before the order id, in
442
+ // order for these constants to be casted by the driver.
443
+ var x = await ( db . Orders . CountAsync ( o => - idMin - 1 + o . OrderId < random . Next ( ) ) ) ;
444
+
445
+ Assert . That ( x , Is . GreaterThan ( 0 ) ) ;
446
+ // Next requires support of both floor and rand
447
+ AssertFunctionInSql ( IsFunctionSupported ( "floor" ) ? "random" : "floor" , spy ) ;
448
+ }
449
+ }
450
+
451
+ [ Test ]
452
+ public async Task CanSelectRandomIntAsync ( )
453
+ {
454
+ using ( var spy = new SqlLogSpy ( ) )
455
+ {
456
+ var random = new Random ( ) ;
457
+ var x =
458
+ await ( db
459
+ . Orders . Select ( o => new { id = o . OrderId , r = random . Next ( ) } )
460
+ . OrderBy ( o => o . id ) . ToListAsync ( ) ) ;
461
+
462
+ Assert . That ( x , Has . Count . GreaterThan ( 0 ) ) ;
463
+ var randomValues = x . Select ( o => o . r ) . Distinct ( ) . ToArray ( ) ;
464
+ Assert . That ( randomValues , Has . All . GreaterThanOrEqualTo ( 0 ) . And . LessThan ( int . MaxValue ) . And . TypeOf < int > ( ) ) ;
465
+
466
+ if ( ! LegacyPreEvaluation && IsFunctionSupported ( "random" ) && IsFunctionSupported ( "floor" ) )
467
+ {
468
+ // Naïve randomness check
469
+ Assert . That (
470
+ randomValues ,
471
+ Has . Length . GreaterThan ( x . Count / 2 ) ,
472
+ "Generated values do not seem very random" ) ;
473
+ }
474
+
475
+ // Next requires support of both floor and rand
476
+ AssertFunctionInSql ( IsFunctionSupported ( "floor" ) ? "random" : "floor" , spy ) ;
477
+ }
478
+ }
479
+
480
+ [ Test ]
481
+ public async Task CanQueryByRandomIntWithMaxAsync ( )
482
+ {
483
+ var idMin = await ( db . Orders . MinAsync ( o => o . OrderId ) ) ;
484
+ using ( var spy = new SqlLogSpy ( ) )
485
+ {
486
+ var random = new Random ( ) ;
487
+ // Dodge a Firebird driver limitation by putting the constants before the order id.
488
+ // This driver cast parameters to their types in some cases for avoiding Firebird complaining of not
489
+ // knowing the type of the condition. For some reasons the driver considers the casting should not be
490
+ // done next to the conditional operator. Having the cast only on one side is enough for avoiding
491
+ // Firebird complain, so moving the constants on the left side have been put before the order id, in
492
+ // order for these constants to be casted by the driver.
493
+ var x = await ( db . Orders . CountAsync ( o => - idMin + o . OrderId <= random . Next ( 10 ) ) ) ;
494
+
495
+ Assert . That ( x , Is . GreaterThan ( 0 ) . And . LessThan ( 11 ) ) ;
496
+ // Next requires support of both floor and rand
497
+ AssertFunctionInSql ( IsFunctionSupported ( "floor" ) ? "random" : "floor" , spy ) ;
498
+ }
499
+ }
500
+
501
+ [ Test ]
502
+ public async Task CanSelectRandomIntWithMaxAsync ( )
503
+ {
504
+ using ( var spy = new SqlLogSpy ( ) )
505
+ {
506
+ var random = new Random ( ) ;
507
+ var x =
508
+ await ( db
509
+ . Orders . Select ( o => new { id = o . OrderId , r = random . Next ( 10 ) } )
510
+ . OrderBy ( o => o . id ) . ToListAsync ( ) ) ;
511
+
512
+ Assert . That ( x , Has . Count . GreaterThan ( 0 ) ) ;
513
+ var randomValues = x . Select ( o => o . r ) . Distinct ( ) . ToArray ( ) ;
514
+ Assert . That ( randomValues , Has . All . GreaterThanOrEqualTo ( 0 ) . And . LessThan ( 10 ) . And . TypeOf < int > ( ) ) ;
515
+
516
+ if ( ! LegacyPreEvaluation && IsFunctionSupported ( "random" ) && IsFunctionSupported ( "floor" ) )
517
+ {
518
+ // Naïve randomness check
519
+ Assert . That (
520
+ randomValues ,
521
+ Has . Length . GreaterThan ( Math . Min ( 10 , x . Count ) / 2 ) ,
522
+ "Generated values do not seem very random" ) ;
523
+ }
524
+
525
+ // Next requires support of both floor and rand
526
+ AssertFunctionInSql ( IsFunctionSupported ( "floor" ) ? "random" : "floor" , spy ) ;
527
+ }
528
+ }
529
+
530
+ [ Test ]
531
+ public async Task CanQueryByRandomIntWithMinMaxAsync ( )
532
+ {
533
+ var idMin = await ( db . Orders . MinAsync ( o => o . OrderId ) ) ;
534
+ using ( var spy = new SqlLogSpy ( ) )
535
+ {
536
+ var random = new Random ( ) ;
537
+ // Dodge a Firebird driver limitation by putting the constants before the order id.
538
+ // This driver cast parameters to their types in some cases for avoiding Firebird complaining of not
539
+ // knowing the type of the condition. For some reasons the driver considers the casting should not be
540
+ // done next to the conditional operator. Having the cast only on one side is enough for avoiding
541
+ // Firebird complain, so moving the constants on the left side have been put before the order id, in
542
+ // order for these constants to be casted by the driver.
543
+ var x = await ( db . Orders . CountAsync ( o => - idMin + o . OrderId < random . Next ( 1 , 10 ) ) ) ;
544
+
545
+ Assert . That ( x , Is . GreaterThan ( 0 ) . And . LessThan ( 10 ) ) ;
546
+ // Next requires support of both floor and rand
547
+ AssertFunctionInSql ( IsFunctionSupported ( "floor" ) ? "random" : "floor" , spy ) ;
548
+ }
549
+ }
550
+
551
+ [ Test ]
552
+ public async Task CanSelectRandomIntWithMinMaxAsync ( )
553
+ {
554
+ using ( var spy = new SqlLogSpy ( ) )
555
+ {
556
+ var random = new Random ( ) ;
557
+ var x =
558
+ await ( db
559
+ . Orders . Select ( o => new { id = o . OrderId , r = random . Next ( 1 , 11 ) } )
560
+ . OrderBy ( o => o . id ) . ToListAsync ( ) ) ;
561
+
562
+ Assert . That ( x , Has . Count . GreaterThan ( 0 ) ) ;
563
+ var randomValues = x . Select ( o => o . r ) . Distinct ( ) . ToArray ( ) ;
564
+ Assert . That ( randomValues , Has . All . GreaterThanOrEqualTo ( 1 ) . And . LessThan ( 11 ) . And . TypeOf < int > ( ) ) ;
565
+
566
+ if ( ! LegacyPreEvaluation && IsFunctionSupported ( "random" ) && IsFunctionSupported ( "floor" ) )
567
+ {
568
+ // Naïve randomness check
569
+ Assert . That (
570
+ randomValues ,
571
+ Has . Length . GreaterThan ( Math . Min ( 10 , x . Count ) / 2 ) ,
572
+ "Generated values do not seem very random" ) ;
573
+ }
574
+
575
+ // Next requires support of both floor and rand
576
+ AssertFunctionInSql ( IsFunctionSupported ( "floor" ) ? "random" : "floor" , spy ) ;
577
+ }
578
+ }
579
+
389
580
private void AssertFunctionInSql ( string functionName , SqlLogSpy spy )
390
581
{
391
582
if ( ! IsFunctionSupported ( functionName ) )
0 commit comments