@@ -291,6 +291,223 @@ public void CanSelectNewGuid()
291
291
} ) ;
292
292
}
293
293
294
+ [ Test ]
295
+ public void CanQueryByRandomDouble ( )
296
+ {
297
+ var isSupported = IsFunctionSupported ( "random" ) ;
298
+ RunTest (
299
+ isSupported ,
300
+ spy =>
301
+ {
302
+ var random = new Random ( ) ;
303
+ var x = db . Orders . Count ( o => o . OrderId > random . NextDouble ( ) ) ;
304
+
305
+ Assert . That ( x , Is . GreaterThan ( 0 ) ) ;
306
+ AssertFunctionInSql ( "random" , spy ) ;
307
+ } ) ;
308
+ }
309
+
310
+ [ Test ]
311
+ public void CanSelectRandomDouble ( )
312
+ {
313
+ var isSupported = IsFunctionSupported ( "random" ) ;
314
+ RunTest (
315
+ isSupported ,
316
+ spy =>
317
+ {
318
+ var random = new Random ( ) ;
319
+ var x =
320
+ db
321
+ . Orders . Select ( o => new { id = o . OrderId , r = random . NextDouble ( ) } )
322
+ . OrderBy ( o => o . id ) . ToList ( ) ;
323
+
324
+ Assert . That ( x , Has . Count . GreaterThan ( 0 ) ) ;
325
+ var randomValues = x . Select ( o => o . r ) . Distinct ( ) . ToArray ( ) ;
326
+ Assert . That ( randomValues , Has . All . GreaterThanOrEqualTo ( 0 ) . And . LessThan ( 1 ) ) ;
327
+
328
+ if ( ! LegacyPreEvaluation && IsFunctionSupported ( "random" ) )
329
+ {
330
+ // Naïve randomness check
331
+ Assert . That (
332
+ randomValues ,
333
+ Has . Length . GreaterThan ( x . Count / 2 ) ,
334
+ "Generated values do not seem very random" ) ;
335
+ }
336
+
337
+ AssertFunctionInSql ( "random" , spy ) ;
338
+ } ) ;
339
+ }
340
+
341
+ [ Test ]
342
+ public void CanQueryByRandomInt ( )
343
+ {
344
+ var isSupported = IsFunctionSupported ( "random" ) && IsFunctionSupported ( "floor" ) ;
345
+ var idMin = db . Orders . Min ( o => o . OrderId ) ;
346
+ RunTest (
347
+ isSupported ,
348
+ spy =>
349
+ {
350
+ var random = new Random ( ) ;
351
+ // Dodge a Firebird driver limitation by putting the constants before the order id.
352
+ // This driver cast parameters to their types in some cases for avoiding Firebird complaining of not
353
+ // knowing the type of the condition. For some reasons the driver considers the casting should not be
354
+ // done next to the conditional operator. Having the cast only on one side is enough for avoiding
355
+ // Firebird complain, so moving the constants on the left side have been put before the order id, in
356
+ // order for these constants to be casted by the driver.
357
+ var x = db . Orders . Count ( o => - idMin - 1 + o . OrderId < random . Next ( ) ) ;
358
+
359
+ Assert . That ( x , Is . GreaterThan ( 0 ) ) ;
360
+ // Next requires support of both floor and rand
361
+ AssertFunctionInSql ( IsFunctionSupported ( "floor" ) ? "random" : "floor" , spy ) ;
362
+ } ) ;
363
+ }
364
+
365
+ [ Test ]
366
+ public void CanSelectRandomInt ( )
367
+ {
368
+ var isSupported = IsFunctionSupported ( "random" ) && IsFunctionSupported ( "floor" ) ;
369
+ RunTest (
370
+ isSupported ,
371
+ spy =>
372
+ {
373
+ var random = new Random ( ) ;
374
+ var x =
375
+ db
376
+ . Orders . Select ( o => new { id = o . OrderId , r = random . Next ( ) } )
377
+ . OrderBy ( o => o . id ) . ToList ( ) ;
378
+
379
+ Assert . That ( x , Has . Count . GreaterThan ( 0 ) ) ;
380
+ var randomValues = x . Select ( o => o . r ) . Distinct ( ) . ToArray ( ) ;
381
+ Assert . That (
382
+ randomValues ,
383
+ Has . All . GreaterThanOrEqualTo ( 0 ) . And . LessThan ( int . MaxValue ) . And . TypeOf < int > ( ) ) ;
384
+
385
+ if ( ! LegacyPreEvaluation && IsFunctionSupported ( "random" ) && IsFunctionSupported ( "floor" ) )
386
+ {
387
+ // Naïve randomness check
388
+ Assert . That (
389
+ randomValues ,
390
+ Has . Length . GreaterThan ( x . Count / 2 ) ,
391
+ "Generated values do not seem very random" ) ;
392
+ }
393
+
394
+ // Next requires support of both floor and rand
395
+ AssertFunctionInSql ( IsFunctionSupported ( "floor" ) ? "random" : "floor" , spy ) ;
396
+ } ) ;
397
+ }
398
+
399
+ [ Test ]
400
+ public void CanQueryByRandomIntWithMax ( )
401
+ {
402
+ var isSupported = IsFunctionSupported ( "random" ) && IsFunctionSupported ( "floor" ) ;
403
+ var idMin = db . Orders . Min ( o => o . OrderId ) ;
404
+ RunTest (
405
+ isSupported ,
406
+ spy =>
407
+ {
408
+ var random = new Random ( ) ;
409
+ // Dodge a Firebird driver limitation by putting the constants before the order id.
410
+ // This driver cast parameters to their types in some cases for avoiding Firebird complaining of not
411
+ // knowing the type of the condition. For some reasons the driver considers the casting should not be
412
+ // done next to the conditional operator. Having the cast only on one side is enough for avoiding
413
+ // Firebird complain, so moving the constants on the left side have been put before the order id, in
414
+ // order for these constants to be casted by the driver.
415
+ var x = db . Orders . Count ( o => - idMin + o . OrderId <= random . Next ( 10 ) ) ;
416
+
417
+ Assert . That ( x , Is . GreaterThan ( 0 ) . And . LessThan ( 11 ) ) ;
418
+ // Next requires support of both floor and rand
419
+ AssertFunctionInSql ( IsFunctionSupported ( "floor" ) ? "random" : "floor" , spy ) ;
420
+ } ) ;
421
+ }
422
+
423
+ [ Test ]
424
+ public void CanSelectRandomIntWithMax ( )
425
+ {
426
+ var isSupported = IsFunctionSupported ( "random" ) && IsFunctionSupported ( "floor" ) ;
427
+ RunTest (
428
+ isSupported ,
429
+ spy =>
430
+ {
431
+ var random = new Random ( ) ;
432
+ var x =
433
+ db
434
+ . Orders . Select ( o => new { id = o . OrderId , r = random . Next ( 10 ) } )
435
+ . OrderBy ( o => o . id ) . ToList ( ) ;
436
+
437
+ Assert . That ( x , Has . Count . GreaterThan ( 0 ) ) ;
438
+ var randomValues = x . Select ( o => o . r ) . Distinct ( ) . ToArray ( ) ;
439
+ Assert . That ( randomValues , Has . All . GreaterThanOrEqualTo ( 0 ) . And . LessThan ( 10 ) . And . TypeOf < int > ( ) ) ;
440
+
441
+ if ( ! LegacyPreEvaluation && IsFunctionSupported ( "random" ) && IsFunctionSupported ( "floor" ) )
442
+ {
443
+ // Naïve randomness check
444
+ Assert . That (
445
+ randomValues ,
446
+ Has . Length . GreaterThan ( Math . Min ( 10 , x . Count ) / 2 ) ,
447
+ "Generated values do not seem very random" ) ;
448
+ }
449
+
450
+ // Next requires support of both floor and rand
451
+ AssertFunctionInSql ( IsFunctionSupported ( "floor" ) ? "random" : "floor" , spy ) ;
452
+ } ) ;
453
+ }
454
+
455
+ [ Test ]
456
+ public void CanQueryByRandomIntWithMinMax ( )
457
+ {
458
+ var isSupported = IsFunctionSupported ( "random" ) && IsFunctionSupported ( "floor" ) ;
459
+ var idMin = db . Orders . Min ( o => o . OrderId ) ;
460
+ RunTest (
461
+ isSupported ,
462
+ spy =>
463
+ {
464
+ var random = new Random ( ) ;
465
+ // Dodge a Firebird driver limitation by putting the constants before the order id.
466
+ // This driver cast parameters to their types in some cases for avoiding Firebird complaining of not
467
+ // knowing the type of the condition. For some reasons the driver considers the casting should not be
468
+ // done next to the conditional operator. Having the cast only on one side is enough for avoiding
469
+ // Firebird complain, so moving the constants on the left side have been put before the order id, in
470
+ // order for these constants to be casted by the driver.
471
+ var x = db . Orders . Count ( o => - idMin + o . OrderId < random . Next ( 1 , 10 ) ) ;
472
+
473
+ Assert . That ( x , Is . GreaterThan ( 0 ) . And . LessThan ( 10 ) ) ;
474
+ // Next requires support of both floor and rand
475
+ AssertFunctionInSql ( IsFunctionSupported ( "floor" ) ? "random" : "floor" , spy ) ;
476
+ } ) ;
477
+ }
478
+
479
+ [ Test ]
480
+ public void CanSelectRandomIntWithMinMax ( )
481
+ {
482
+ var isSupported = IsFunctionSupported ( "random" ) && IsFunctionSupported ( "floor" ) ;
483
+ RunTest (
484
+ isSupported ,
485
+ spy =>
486
+ {
487
+ var random = new Random ( ) ;
488
+ var x =
489
+ db
490
+ . Orders . Select ( o => new { id = o . OrderId , r = random . Next ( 1 , 11 ) } )
491
+ . OrderBy ( o => o . id ) . ToList ( ) ;
492
+
493
+ Assert . That ( x , Has . Count . GreaterThan ( 0 ) ) ;
494
+ var randomValues = x . Select ( o => o . r ) . Distinct ( ) . ToArray ( ) ;
495
+ Assert . That ( randomValues , Has . All . GreaterThanOrEqualTo ( 1 ) . And . LessThan ( 11 ) . And . TypeOf < int > ( ) ) ;
496
+
497
+ if ( ! LegacyPreEvaluation && IsFunctionSupported ( "random" ) && IsFunctionSupported ( "floor" ) )
498
+ {
499
+ // Naïve randomness check
500
+ Assert . That (
501
+ randomValues ,
502
+ Has . Length . GreaterThan ( Math . Min ( 10 , x . Count ) / 2 ) ,
503
+ "Generated values do not seem very random" ) ;
504
+ }
505
+
506
+ // Next requires support of both floor and rand
507
+ AssertFunctionInSql ( IsFunctionSupported ( "floor" ) ? "random" : "floor" , spy ) ;
508
+ } ) ;
509
+ }
510
+
294
511
private void AssertFunctionInSql ( string functionName , SqlLogSpy spy )
295
512
{
296
513
if ( ! IsFunctionSupported ( functionName ) )
0 commit comments