Skip to content

Commit 03c1ba5

Browse files
authoredDec 22, 2020
Query: Add EF.Functions.Random (#23145)
Resolves #16141
1 parent e5425e5 commit 03c1ba5

File tree

15 files changed

+368
-8
lines changed

15 files changed

+368
-8
lines changed
 

‎EFCore.Runtime.slnf

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@
1717
"src\\EFCore\\EFCore.csproj",
1818
"src\\Microsoft.Data.Sqlite.Core\\Microsoft.Data.Sqlite.Core.csproj",
1919
"test\\EFCore.Analyzers.Tests\\EFCore.Analyzers.Tests.csproj",
20+
"test\\EFCore.AspNet.InMemory.FunctionalTests\\EFCore.AspNet.InMemory.FunctionalTests.csproj",
2021
"test\\EFCore.AspNet.Specification.Tests\\EFCore.AspNet.Specification.Tests.csproj",
2122
"test\\EFCore.AspNet.SqlServer.FunctionalTests\\EFCore.AspNet.SqlServer.FunctionalTests.csproj",
2223
"test\\EFCore.AspNet.Sqlite.FunctionalTests\\EFCore.AspNet.Sqlite.FunctionalTests.csproj",
23-
"test\\EFCore.AspNet.InMemory.FunctionalTests\\EFCore.AspNet.InMemory.FunctionalTests.csproj",
2424
"test\\EFCore.Cosmos.FunctionalTests\\EFCore.Cosmos.FunctionalTests.csproj",
2525
"test\\EFCore.Cosmos.Tests\\EFCore.Cosmos.Tests.csproj",
2626
"test\\EFCore.CrossStore.FunctionalTests\\EFCore.CrossStore.FunctionalTests.csproj",

‎EFCore.Sqlite.slnf

+3
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,9 @@
1313
"src\\EFCore\\EFCore.csproj",
1414
"src\\Microsoft.Data.Sqlite.Core\\Microsoft.Data.Sqlite.Core.csproj",
1515
"test\\EFCore.Analyzers.Tests\\EFCore.Analyzers.Tests.csproj",
16+
"test\\EFCore.AspNet.InMemory.FunctionalTests\\EFCore.AspNet.InMemory.FunctionalTests.csproj",
17+
"test\\EFCore.AspNet.Specification.Tests\\EFCore.AspNet.Specification.Tests.csproj",
18+
"test\\EFCore.AspNet.Sqlite.FunctionalTests\\EFCore.AspNet.Sqlite.FunctionalTests.csproj",
1619
"test\\EFCore.Design.Tests\\EFCore.Design.Tests.csproj",
1720
"test\\EFCore.InMemory.FunctionalTests\\EFCore.InMemory.FunctionalTests.csproj",
1821
"test\\EFCore.InMemory.Tests\\EFCore.InMemory.Tests.csproj",

‎EFCore.slnf

+1-1
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@
2424
"src\\dotnet-ef\\dotnet-ef.csproj",
2525
"src\\ef\\ef.csproj",
2626
"test\\EFCore.Analyzers.Tests\\EFCore.Analyzers.Tests.csproj",
27+
"test\\EFCore.AspNet.InMemory.FunctionalTests\\EFCore.AspNet.InMemory.FunctionalTests.csproj",
2728
"test\\EFCore.AspNet.Specification.Tests\\EFCore.AspNet.Specification.Tests.csproj",
2829
"test\\EFCore.AspNet.SqlServer.FunctionalTests\\EFCore.AspNet.SqlServer.FunctionalTests.csproj",
2930
"test\\EFCore.AspNet.Sqlite.FunctionalTests\\EFCore.AspNet.Sqlite.FunctionalTests.csproj",
30-
"test\\EFCore.AspNet.InMemory.FunctionalTests\\EFCore.AspNet.InMemory.FunctionalTests.csproj"
3131
"test\\EFCore.Cosmos.FunctionalTests\\EFCore.Cosmos.FunctionalTests.csproj",
3232
"test\\EFCore.Cosmos.Tests\\EFCore.Cosmos.Tests.csproj",
3333
"test\\EFCore.CrossStore.FunctionalTests\\EFCore.CrossStore.FunctionalTests.csproj",

‎src/EFCore.Cosmos/Query/Internal/CosmosMethodCallTranslatorProvider.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ public CosmosMethodCallTranslatorProvider(
4141
{
4242
new EqualsTranslator(sqlExpressionFactory),
4343
new StringMethodTranslator(sqlExpressionFactory),
44-
new ContainsTranslator(sqlExpressionFactory)
44+
new ContainsTranslator(sqlExpressionFactory),
45+
new RandomTranslator(sqlExpressionFactory)
4546
//new LikeTranslator(sqlExpressionFactory),
4647
//new EnumHasFlagTranslator(sqlExpressionFactory),
4748
//new GetValueOrDefaultTranslator(sqlExpressionFactory),
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Reflection;
7+
using JetBrains.Annotations;
8+
using Microsoft.EntityFrameworkCore.Diagnostics;
9+
using Microsoft.EntityFrameworkCore.Utilities;
10+
11+
namespace Microsoft.EntityFrameworkCore.Cosmos.Query.Internal
12+
{
13+
/// <summary>
14+
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
15+
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
16+
/// any release. You should only use it directly in your code with extreme caution and knowing that
17+
/// doing so can result in application failures when updating to a new Entity Framework Core release.
18+
/// </summary>
19+
public class RandomTranslator : IMethodCallTranslator
20+
{
21+
private static readonly MethodInfo _methodInfo = typeof(DbFunctionsExtensions).GetRuntimeMethod(nameof(DbFunctionsExtensions.Random), new[] { typeof(DbFunctions) });
22+
private readonly ISqlExpressionFactory _sqlExpressionFactory;
23+
24+
/// <summary>
25+
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
26+
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
27+
/// any release. You should only use it directly in your code with extreme caution and knowing that
28+
/// doing so can result in application failures when updating to a new Entity Framework Core release.
29+
/// </summary>
30+
public RandomTranslator([NotNull] ISqlExpressionFactory sqlExpressionFactory)
31+
{
32+
_sqlExpressionFactory = sqlExpressionFactory;
33+
}
34+
35+
/// <summary>
36+
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
37+
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
38+
/// any release. You should only use it directly in your code with extreme caution and knowing that
39+
/// doing so can result in application failures when updating to a new Entity Framework Core release.
40+
/// </summary>
41+
public virtual SqlExpression Translate(
42+
SqlExpression instance,
43+
MethodInfo method,
44+
IReadOnlyList<SqlExpression> arguments,
45+
IDiagnosticsLogger<DbLoggerCategory.Query> logger)
46+
{
47+
Check.NotNull(method, nameof(method));
48+
Check.NotNull(arguments, nameof(arguments));
49+
Check.NotNull(logger, nameof(logger));
50+
51+
return _methodInfo.Equals(method)
52+
? _sqlExpressionFactory.Function(
53+
"RAND",
54+
Array.Empty<SqlExpression>(),
55+
method.ReturnType)
56+
: null;
57+
}
58+
}
59+
}

‎src/EFCore.InMemory/Query/Internal/InMemoryExpressionTranslatingExpressionVisitor.cs

+11
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ public class InMemoryExpressionTranslatingExpressionVisitor : ExpressionVisitor
5151
private static readonly MethodInfo _likeMethodInfoWithEscape = typeof(DbFunctionsExtensions).GetRequiredRuntimeMethod(
5252
nameof(DbFunctionsExtensions.Like), new[] { typeof(DbFunctions), typeof(string), typeof(string), typeof(string) });
5353

54+
private static readonly MethodInfo _randomMethodInfo = typeof(DbFunctionsExtensions).GetRequiredRuntimeMethod(
55+
nameof(DbFunctionsExtensions.Random), new[] { typeof(DbFunctions) });
56+
57+
private static readonly MethodInfo _randomNextDoubleMethodInfo = typeof(Random).GetRequiredRuntimeMethod(
58+
nameof(Random.NextDouble), Array.Empty<Type>());
59+
5460
private static readonly MethodInfo _inMemoryLikeMethodInfo =
5561
typeof(InMemoryExpressionTranslatingExpressionVisitor).GetRequiredDeclaredMethod(nameof(InMemoryLike));
5662

@@ -750,6 +756,11 @@ static Expression RemapLambda(GroupingElementExpression groupingElement, LambdaE
750756
return Expression.Call(_inMemoryLikeMethodInfo, visitedArguments);
751757
}
752758

759+
if (methodCallExpression.Method == _randomMethodInfo)
760+
{
761+
return Expression.Call(Expression.New(typeof(Random)), _randomNextDoubleMethodInfo);
762+
}
763+
753764
Expression? @object = null;
754765
Expression[] arguments;
755766
var method = methodCallExpression.Method;
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Reflection;
7+
using JetBrains.Annotations;
8+
using Microsoft.EntityFrameworkCore.Diagnostics;
9+
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
10+
using Microsoft.EntityFrameworkCore.Utilities;
11+
12+
#nullable enable
13+
14+
namespace Microsoft.EntityFrameworkCore.Query.Internal
15+
{
16+
/// <summary>
17+
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
18+
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
19+
/// any release. You should only use it directly in your code with extreme caution and knowing that
20+
/// doing so can result in application failures when updating to a new Entity Framework Core release.
21+
/// </summary>
22+
public class RandomTranslator : IMethodCallTranslator
23+
{
24+
private static readonly MethodInfo _methodInfo = typeof(DbFunctionsExtensions).GetRequiredRuntimeMethod(nameof(DbFunctionsExtensions.Random), new[] { typeof(DbFunctions) });
25+
private readonly ISqlExpressionFactory _sqlExpressionFactory;
26+
27+
/// <summary>
28+
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
29+
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
30+
/// any release. You should only use it directly in your code with extreme caution and knowing that
31+
/// doing so can result in application failures when updating to a new Entity Framework Core release.
32+
/// </summary>
33+
public RandomTranslator([NotNull] ISqlExpressionFactory sqlExpressionFactory)
34+
{
35+
_sqlExpressionFactory = sqlExpressionFactory;
36+
}
37+
38+
/// <summary>
39+
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
40+
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
41+
/// any release. You should only use it directly in your code with extreme caution and knowing that
42+
/// doing so can result in application failures when updating to a new Entity Framework Core release.
43+
/// </summary>
44+
public virtual SqlExpression? Translate(
45+
SqlExpression? instance,
46+
MethodInfo method,
47+
IReadOnlyList<SqlExpression> arguments,
48+
IDiagnosticsLogger<DbLoggerCategory.Query> logger)
49+
{
50+
Check.NotNull(method, nameof(method));
51+
Check.NotNull(arguments, nameof(arguments));
52+
Check.NotNull(logger, nameof(logger));
53+
54+
return _methodInfo.Equals(method)
55+
? _sqlExpressionFactory.Function(
56+
"RAND",
57+
Array.Empty<SqlExpression>(),
58+
nullable: false,
59+
argumentsPropagateNullability: Array.Empty<bool>(),
60+
method.ReturnType)
61+
: null;
62+
}
63+
}
64+
}

‎src/EFCore.Relational/Query/RelationalMethodCallTranslatorProvider.cs

+2-1
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,8 @@ public RelationalMethodCallTranslatorProvider([NotNull] RelationalMethodCallTran
5858
new EnumHasFlagTranslator(sqlExpressionFactory),
5959
new GetValueOrDefaultTranslator(sqlExpressionFactory),
6060
new ComparisonTranslator(sqlExpressionFactory),
61-
new ByteArraySequenceEqualTranslator(sqlExpressionFactory)
61+
new ByteArraySequenceEqualTranslator(sqlExpressionFactory),
62+
new RandomTranslator(sqlExpressionFactory)
6263
});
6364
_sqlExpressionFactory = sqlExpressionFactory;
6465
}

‎src/EFCore.Sqlite.Core/Query/Internal/SqliteMethodCallTranslatorProvider.cs

+1
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ public SqliteMethodCallTranslatorProvider([NotNull] RelationalMethodCallTranslat
3737
new SqliteHexMethodTranslator(sqlExpressionFactory),
3838
new SqliteMathTranslator(sqlExpressionFactory),
3939
new SqliteObjectToStringTranslator(sqlExpressionFactory),
40+
new SqliteRandomTranslator(sqlExpressionFactory),
4041
new SqliteRegexMethodTranslator(sqlExpressionFactory),
4142
new SqliteStringMethodTranslator(sqlExpressionFactory),
4243
new SqliteSubstrMethodTranslator(sqlExpressionFactory)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System;
5+
using System.Collections.Generic;
6+
using System.Reflection;
7+
using JetBrains.Annotations;
8+
using Microsoft.EntityFrameworkCore.Diagnostics;
9+
using Microsoft.EntityFrameworkCore.Query;
10+
using Microsoft.EntityFrameworkCore.Query.SqlExpressions;
11+
using Microsoft.EntityFrameworkCore.Utilities;
12+
13+
namespace Microsoft.EntityFrameworkCore.Sqlite.Query.Internal
14+
{
15+
/// <summary>
16+
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
17+
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
18+
/// any release. You should only use it directly in your code with extreme caution and knowing that
19+
/// doing so can result in application failures when updating to a new Entity Framework Core release.
20+
/// </summary>
21+
public class SqliteRandomTranslator : IMethodCallTranslator
22+
{
23+
private static readonly MethodInfo _methodInfo = typeof(DbFunctionsExtensions).GetRuntimeMethod(nameof(DbFunctionsExtensions.Random), new[] { typeof(DbFunctions) });
24+
private readonly ISqlExpressionFactory _sqlExpressionFactory;
25+
26+
/// <summary>
27+
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
28+
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
29+
/// any release. You should only use it directly in your code with extreme caution and knowing that
30+
/// doing so can result in application failures when updating to a new Entity Framework Core release.
31+
/// </summary>
32+
public SqliteRandomTranslator([NotNull] ISqlExpressionFactory sqlExpressionFactory)
33+
{
34+
_sqlExpressionFactory = sqlExpressionFactory;
35+
}
36+
37+
/// <summary>
38+
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
39+
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
40+
/// any release. You should only use it directly in your code with extreme caution and knowing that
41+
/// doing so can result in application failures when updating to a new Entity Framework Core release.
42+
/// </summary>
43+
public virtual SqlExpression Translate(
44+
SqlExpression instance,
45+
MethodInfo method,
46+
IReadOnlyList<SqlExpression> arguments,
47+
IDiagnosticsLogger<DbLoggerCategory.Query> logger)
48+
{
49+
Check.NotNull(method, nameof(method));
50+
Check.NotNull(arguments, nameof(arguments));
51+
Check.NotNull(logger, nameof(logger));
52+
53+
// Issue #15586: Query: TypeCompatibility chart for inference.
54+
return _methodInfo.Equals(method)
55+
? _sqlExpressionFactory.Function(
56+
"abs",
57+
new SqlExpression[]
58+
{
59+
_sqlExpressionFactory.Divide(
60+
_sqlExpressionFactory.Function(
61+
"random",
62+
Array.Empty<SqlExpression>(),
63+
nullable: false,
64+
argumentsPropagateNullability: Array.Empty<bool>(),
65+
method.ReturnType),
66+
_sqlExpressionFactory.Constant(9223372036854780000.0))
67+
},
68+
nullable: false,
69+
argumentsPropagateNullability: Array.Empty<bool>(),
70+
method.ReturnType)
71+
: null;
72+
}
73+
}
74+
}

‎src/EFCore/DbFunctionsExtensions.cs

+12-4
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ public static bool Like(
3434
[CanBeNull] this DbFunctions _,
3535
[CanBeNull] string matchExpression,
3636
[CanBeNull] string pattern)
37-
=> LikeCore(matchExpression, pattern, escapeCharacter: null);
37+
=> throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Like)));
3838

3939
/// <summary>
4040
/// <para>
@@ -61,9 +61,17 @@ public static bool Like(
6161
[CanBeNull] string matchExpression,
6262
[CanBeNull] string pattern,
6363
[CanBeNull] string escapeCharacter)
64-
=> LikeCore(matchExpression, pattern, escapeCharacter);
65-
66-
private static bool LikeCore(string matchExpression, string pattern, string escapeCharacter)
6764
=> throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Like)));
65+
66+
/// <summary>
67+
/// <para>
68+
/// A random double number generator which generates a number between 0 and 1, exclusive.
69+
/// This is usually directly translated to server.
70+
/// </para>
71+
/// </summary>
72+
/// <param name="_"> The DbFunctions instance. </param>
73+
/// <returns> A random double number between 0 and 1, exclusive. </returns>
74+
public static double Random([CanBeNull] this DbFunctions _)
75+
=> throw new InvalidOperationException(CoreStrings.FunctionOnClient(nameof(Random)));
6876
}
6977
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System.Threading.Tasks;
5+
using Microsoft.EntityFrameworkCore.TestModels.Northwind;
6+
using Microsoft.EntityFrameworkCore.TestUtilities;
7+
using Xunit;
8+
using Xunit.Abstractions;
9+
10+
namespace Microsoft.EntityFrameworkCore.Query
11+
{
12+
public class NorthwindDbFunctionsQueryCosmosTest : NorthwindDbFunctionsQueryTestBase<NorthwindQueryCosmosFixture<NoopModelCustomizer>>
13+
{
14+
public NorthwindDbFunctionsQueryCosmosTest(
15+
NorthwindQueryCosmosFixture<NoopModelCustomizer> fixture,
16+
ITestOutputHelper testOutputHelper)
17+
: base(fixture)
18+
{
19+
ClearLog();
20+
}
21+
22+
public override Task Like_all_literals(bool async)
23+
{
24+
return AssertTranslationFailed(() => base.Like_all_literals(async));
25+
}
26+
27+
public override Task Like_all_literals_with_escape(bool async)
28+
{
29+
return AssertTranslationFailed(() => base.Like_all_literals_with_escape(async));
30+
}
31+
32+
public override Task Like_literal(bool async)
33+
{
34+
return AssertTranslationFailed(() => base.Like_literal(async));
35+
}
36+
37+
public override Task Like_literal_with_escape(bool async)
38+
{
39+
return AssertTranslationFailed(() => base.Like_literal_with_escape(async));
40+
}
41+
42+
public override Task Like_identity(bool async)
43+
{
44+
return AssertTranslationFailed(() => base.Like_identity(async));
45+
}
46+
47+
public override async Task Random_return_less_than_1(bool async)
48+
{
49+
await base.Random_return_less_than_1(async);
50+
51+
AssertSql(
52+
@"SELECT COUNT(1) AS c
53+
FROM root c
54+
WHERE ((c[""Discriminator""] = ""Order"") AND (RAND() < 1.0))");
55+
}
56+
57+
public override async Task Random_return_greater_than_0(bool async)
58+
{
59+
await base.Random_return_greater_than_0(async);
60+
61+
AssertSql(
62+
@"SELECT COUNT(1) AS c
63+
FROM root c
64+
WHERE ((c[""Discriminator""] = ""Order"") AND (RAND() >= 0.0))");
65+
}
66+
67+
private void AssertSql(params string[] expected)
68+
=> Fixture.TestSqlLoggerFactory.AssertBaseline(expected);
69+
70+
protected void ClearLog()
71+
=> Fixture.TestSqlLoggerFactory.Clear();
72+
}
73+
}

‎test/EFCore.Specification.Tests/Query/NorthwindDbFunctionsQueryTestBase.cs

+20
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,26 @@ public virtual Task Like_all_literals_with_escape(bool async)
6767
c => EF.Functions.Like("%", "!%", "!"),
6868
c => "%".Contains("%"));
6969

70+
[ConditionalTheory]
71+
[MemberData(nameof(IsAsyncData))]
72+
public virtual Task Random_return_less_than_1(bool async)
73+
=> AssertCount(
74+
async,
75+
ss => ss.Set<Order>(),
76+
ss => ss.Set<Order>(),
77+
ss => EF.Functions.Random() < 1,
78+
c => true);
79+
80+
[ConditionalTheory]
81+
[MemberData(nameof(IsAsyncData))]
82+
public virtual Task Random_return_greater_than_0(bool async)
83+
=> AssertCount(
84+
async,
85+
ss => ss.Set<Order>(),
86+
ss => ss.Set<Order>(),
87+
ss => EF.Functions.Random() >= 0,
88+
c => true);
89+
7090
protected NorthwindContext CreateContext()
7191
=> Fixture.CreateContext();
7292
}

‎test/EFCore.SqlServer.FunctionalTests/Query/NorthwindDbFunctionsQuerySqlServerTest.cs

+20
Original file line numberDiff line numberDiff line change
@@ -1216,6 +1216,26 @@ FROM [Orders] AS [o]
12161216
}
12171217
}
12181218

1219+
public override async Task Random_return_less_than_1(bool async)
1220+
{
1221+
await base.Random_return_less_than_1(async);
1222+
1223+
AssertSql(
1224+
@"SELECT COUNT(*)
1225+
FROM [Orders] AS [o]
1226+
WHERE RAND() < 1.0E0");
1227+
}
1228+
1229+
public override async Task Random_return_greater_than_0(bool async)
1230+
{
1231+
await base.Random_return_greater_than_0(async);
1232+
1233+
AssertSql(
1234+
@"SELECT COUNT(*)
1235+
FROM [Orders] AS [o]
1236+
WHERE RAND() >= 0.0E0");
1237+
}
1238+
12191239
private void AssertSql(params string[] expected)
12201240
=> Fixture.TestSqlLoggerFactory.AssertBaseline(expected);
12211241
}

‎test/EFCore.Sqlite.FunctionalTests/Query/NorthwindDbFunctionsQuerySqliteTest.cs

+25
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,31 @@ protected override string CaseInsensitiveCollation
4343
protected override string CaseSensitiveCollation
4444
=> "BINARY";
4545

46+
public override async Task Random_return_less_than_1(bool async)
47+
{
48+
await AssertCount(
49+
async,
50+
ss => ss.Set<Order>(),
51+
ss => ss.Set<Order>(),
52+
ss => EF.Functions.Random() <= 1,
53+
c => true);
54+
55+
AssertSql(
56+
@"SELECT COUNT(*)
57+
FROM ""Orders"" AS ""o""
58+
WHERE abs(random() / 9.2233720368547799E+18) <= 1.0");
59+
}
60+
61+
public override async Task Random_return_greater_than_0(bool async)
62+
{
63+
await base.Random_return_greater_than_0(async);
64+
65+
AssertSql(
66+
@"SELECT COUNT(*)
67+
FROM ""Orders"" AS ""o""
68+
WHERE abs(random() / 9.2233720368547799E+18) >= 0.0");
69+
}
70+
4671
private void AssertSql(params string[] expected)
4772
=> Fixture.TestSqlLoggerFactory.AssertBaseline(expected);
4873
}

0 commit comments

Comments
 (0)
Please sign in to comment.