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