@@ -291,6 +291,223 @@ public void CanSelectNewGuid()
291291} ) ;
292292}
293293
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+
294511private void AssertFunctionInSql ( string functionName , SqlLogSpy spy )
295512{
296513if ( ! IsFunctionSupported ( functionName ) )
0 commit comments