Skip to content

Commit 8337ade

Browse files
committed
Merge branch 'release/9.0' into main
2 parents 34ee81a + c18fc67 commit 8337ade

File tree

15 files changed

+182
-77
lines changed

15 files changed

+182
-77
lines changed

Diff for: src/EFCore.Design/Design/Internal/AppServiceProviderFactory.cs

+26
Original file line numberDiff line numberDiff line change
@@ -89,4 +89,30 @@ private IServiceProvider CreateEmptyServiceProvider()
8989

9090
return new ServiceCollection().BuildServiceProvider();
9191
}
92+
93+
/// <summary>
94+
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
95+
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
96+
/// any release. You should only use it directly in your code with extreme caution and knowing that
97+
/// doing so can result in application failures when updating to a new Entity Framework Core release.
98+
/// </summary>
99+
public static void SetEnvironment(IOperationReporter reporter)
100+
{
101+
var aspnetCoreEnvironment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
102+
var dotnetEnvironment = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT");
103+
var environment = aspnetCoreEnvironment
104+
?? dotnetEnvironment
105+
?? "Development";
106+
if (aspnetCoreEnvironment == null)
107+
{
108+
Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", environment);
109+
}
110+
111+
if (dotnetEnvironment == null)
112+
{
113+
Environment.SetEnvironmentVariable("DOTNET_ENVIRONMENT", environment);
114+
}
115+
116+
reporter.WriteVerbose(DesignStrings.UsingEnvironment(environment));
117+
}
92118
}

Diff for: src/EFCore.Design/Design/Internal/DatabaseOperations.cs

+3
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ namespace Microsoft.EntityFrameworkCore.Design.Internal;
1111
/// </summary>
1212
public class DatabaseOperations
1313
{
14+
private readonly IOperationReporter _reporter;
1415
private readonly string _projectDir;
1516
private readonly string? _rootNamespace;
1617
private readonly string? _language;
@@ -34,6 +35,7 @@ public DatabaseOperations(
3435
bool nullable,
3536
string[]? args)
3637
{
38+
_reporter = reporter;
3739
_projectDir = projectDir;
3840
_rootNamespace = rootNamespace;
3941
_language = language;
@@ -73,6 +75,7 @@ public virtual SavedModelFiles ScaffoldContext(
7375
? Path.GetFullPath(Path.Combine(_projectDir, outputContextDir))
7476
: outputDir;
7577

78+
AppServiceProviderFactory.SetEnvironment(_reporter);
7679
var services = _servicesBuilder.Build(provider);
7780
using var scope = services.CreateScope();
7881

Diff for: src/EFCore.Design/Design/Internal/DbContextOperations.cs

+1-16
Original file line numberDiff line numberDiff line change
@@ -503,22 +503,7 @@ private IDictionary<Type, Func<DbContext>> FindContextTypes(string? name = null,
503503
{
504504
_reporter.WriteVerbose(DesignStrings.FindingContexts);
505505

506-
var aspnetCoreEnvironment = Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT");
507-
var dotnetEnvironment = Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT");
508-
var environment = aspnetCoreEnvironment
509-
?? dotnetEnvironment
510-
?? "Development";
511-
if (aspnetCoreEnvironment == null)
512-
{
513-
Environment.SetEnvironmentVariable("ASPNETCORE_ENVIRONMENT", environment);
514-
}
515-
516-
if (dotnetEnvironment == null)
517-
{
518-
Environment.SetEnvironmentVariable("DOTNET_ENVIRONMENT", environment);
519-
}
520-
521-
_reporter.WriteVerbose(DesignStrings.UsingEnvironment(environment));
506+
AppServiceProviderFactory.SetEnvironment(_reporter);
522507

523508
var contexts = new Dictionary<Type, Func<DbContext>?>();
524509

Diff for: test/EFCore.Design.Tests/Design/Internal/DatabaseOperationsTest.cs

+68-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Licensed to the .NET Foundation under one or more agreements.
22
// The .NET Foundation licenses this file to you under the MIT license.
33

4+
using Microsoft.EntityFrameworkCore.Internal;
5+
46
namespace Microsoft.EntityFrameworkCore.Design.Internal;
57

68
public class DatabaseOperationsTest
@@ -10,16 +12,80 @@ public void Can_pass_null_args()
1012
{
1113
// Even though newer versions of the tools will pass an empty array
1214
// older versions of the tools can pass null args.
15+
CreateOperations(null);
16+
}
17+
18+
[ConditionalFact]
19+
public void ScaffoldContext_throws_exceptions_for_invalid_context_name()
20+
{
21+
ValidateContextNameInReverseEngineerGenerator("Invalid!CSharp*Class&Name");
22+
ValidateContextNameInReverseEngineerGenerator("1CSharpClassNameCannotStartWithNumber");
23+
ValidateContextNameInReverseEngineerGenerator("volatile");
24+
}
25+
26+
private void ValidateContextNameInReverseEngineerGenerator(string contextName)
27+
{
28+
var operations = CreateOperations([]);
29+
30+
Assert.Equal(
31+
DesignStrings.ContextClassNotValidCSharpIdentifier(contextName),
32+
Assert.Throws<ArgumentException>(
33+
() => operations.ScaffoldContext(
34+
"Microsoft.EntityFrameworkCore.SqlServer",
35+
"connectionstring",
36+
"",
37+
"",
38+
dbContextClassName: contextName,
39+
null,
40+
null,
41+
"FakeNamespace",
42+
contextNamespace: null,
43+
useDataAnnotations: false,
44+
overwriteFiles: true,
45+
useDatabaseNames: false,
46+
suppressOnConfiguring: true,
47+
noPluralize: false))
48+
.Message);
49+
}
50+
51+
[ConditionalFact]
52+
[SqlServerConfiguredCondition]
53+
public void ScaffoldContext_sets_environment()
54+
{
55+
var operations = CreateOperations([]);
56+
operations.ScaffoldContext(
57+
"Microsoft.EntityFrameworkCore.SqlServer",
58+
TestEnvironment.DefaultConnection,
59+
"",
60+
"",
61+
dbContextClassName: nameof(TestContext),
62+
schemas: ["Empty"],
63+
null,
64+
null,
65+
contextNamespace: null,
66+
useDataAnnotations: false,
67+
overwriteFiles: true,
68+
useDatabaseNames: false,
69+
suppressOnConfiguring: true,
70+
noPluralize: false);
71+
72+
Assert.Equal("Development", Environment.GetEnvironmentVariable("ASPNETCORE_ENVIRONMENT"));
73+
Assert.Equal("Development", Environment.GetEnvironmentVariable("DOTNET_ENVIRONMENT"));
74+
}
75+
76+
private static DatabaseOperations CreateOperations(string[] args)
77+
{
1378
var assembly = MockAssembly.Create(typeof(TestContext));
14-
_ = new TestDatabaseOperations(
79+
var operations = new DatabaseOperations(
1580
new TestOperationReporter(),
1681
assembly,
1782
assembly,
1883
"projectDir",
1984
"RootNamespace",
2085
"C#",
2186
nullable: false,
22-
args: null);
87+
args: args);
88+
return operations;
2389
}
2490

2591
public class TestContext : DbContext;

Diff for: test/EFCore.Design.Tests/Migrations/Design/CSharpMigrationOperationGeneratorTest.cs

+2-2
Original file line numberDiff line numberDiff line change
@@ -2453,7 +2453,7 @@ public void InsertDataOperation_required_empty_array()
24532453
Assert.Single(o.Columns);
24542454
Assert.Equal(1, o.Values.GetLength(0));
24552455
Assert.Equal(1, o.Values.GetLength(1));
2456-
Assert.Equal([], (string[])o.Values[0, 0]);
2456+
Assert.Equal(new string[0], (string[])o.Values[0, 0]);
24572457
});
24582458

24592459
[ConditionalFact]
@@ -2478,7 +2478,7 @@ public void InsertDataOperation_required_empty_array_composite()
24782478
Assert.Equal(1, o.Values.GetLength(0));
24792479
Assert.Equal(3, o.Values.GetLength(1));
24802480
Assert.Null(o.Values[0, 1]);
2481-
Assert.Equal([], (string[])o.Values[0, 2]);
2481+
Assert.Equal(new string[0], (string[])o.Values[0, 2]);
24822482
});
24832483

24842484
[ConditionalFact]

Diff for: test/EFCore.Design.Tests/Scaffolding/Internal/ReverseEngineeringConfigurationTests.cs

-38
This file was deleted.

Diff for: test/EFCore.Design.Tests/TestUtilities/TestDatabaseOperations.cs

-16
This file was deleted.

Diff for: test/EFCore.SqlServer.FunctionalTests/Query/GearsOfWarQuerySqlServerTest.cs

+14
Original file line numberDiff line numberDiff line change
@@ -7395,6 +7395,20 @@ FROM [Gears] AS [g]
73957395
""");
73967396
}
73977397

7398+
public override async Task Coalesce_with_non_root_evaluatable_Convert(bool async)
7399+
{
7400+
await base.Coalesce_with_non_root_evaluatable_Convert(async);
7401+
7402+
AssertSql(
7403+
"""
7404+
@__rank_0='1' (Nullable = true)
7405+
7406+
SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Rank]
7407+
FROM [Gears] AS [g]
7408+
WHERE @__rank_0 = [g].[Rank]
7409+
""");
7410+
}
7411+
73987412
[ConditionalTheory]
73997413
[MemberData(nameof(IsAsyncData))]
74007414
public async Task DataLength_function_for_string_parameter(bool async)

Diff for: test/EFCore.SqlServer.FunctionalTests/Query/TPCGearsOfWarQuerySqlServerTest.cs

+20
Original file line numberDiff line numberDiff line change
@@ -9933,6 +9933,26 @@ FROM [Officers] AS [o]
99339933
""");
99349934
}
99359935

9936+
public override async Task Coalesce_with_non_root_evaluatable_Convert(bool async)
9937+
{
9938+
await base.Coalesce_with_non_root_evaluatable_Convert(async);
9939+
9940+
AssertSql(
9941+
"""
9942+
@__rank_0='1' (Nullable = true)
9943+
9944+
SELECT [u].[Nickname], [u].[SquadId], [u].[AssignedCityName], [u].[CityOfBirthName], [u].[FullName], [u].[HasSoulPatch], [u].[LeaderNickname], [u].[LeaderSquadId], [u].[Rank], [u].[Discriminator]
9945+
FROM (
9946+
SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Rank], N'Gear' AS [Discriminator]
9947+
FROM [Gears] AS [g]
9948+
UNION ALL
9949+
SELECT [o].[Nickname], [o].[SquadId], [o].[AssignedCityName], [o].[CityOfBirthName], [o].[FullName], [o].[HasSoulPatch], [o].[LeaderNickname], [o].[LeaderSquadId], [o].[Rank], N'Officer' AS [Discriminator]
9950+
FROM [Officers] AS [o]
9951+
) AS [u]
9952+
WHERE @__rank_0 = [u].[Rank]
9953+
""");
9954+
}
9955+
99369956
[ConditionalTheory]
99379957
[MemberData(nameof(IsAsyncData))]
99389958
public async Task DataLength_function_for_string_parameter(bool async)

Diff for: test/EFCore.SqlServer.FunctionalTests/Query/TPTGearsOfWarQuerySqlServerTest.cs

+17
Original file line numberDiff line numberDiff line change
@@ -8393,6 +8393,23 @@ FROM [Gears] AS [g]
83938393
""");
83948394
}
83958395

8396+
public override async Task Coalesce_with_non_root_evaluatable_Convert(bool async)
8397+
{
8398+
await base.Coalesce_with_non_root_evaluatable_Convert(async);
8399+
8400+
AssertSql(
8401+
"""
8402+
@__rank_0='1' (Nullable = true)
8403+
8404+
SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[Rank], CASE
8405+
WHEN [o].[Nickname] IS NOT NULL THEN N'Officer'
8406+
END AS [Discriminator]
8407+
FROM [Gears] AS [g]
8408+
LEFT JOIN [Officers] AS [o] ON [g].[Nickname] = [o].[Nickname] AND [g].[SquadId] = [o].[SquadId]
8409+
WHERE @__rank_0 = [g].[Rank]
8410+
""");
8411+
}
8412+
83968413
[ConditionalTheory]
83978414
[MemberData(nameof(IsAsyncData))]
83988415
public async Task DataLength_function_for_string_parameter(bool async)

Diff for: test/EFCore.SqlServer.FunctionalTests/Query/TemporalGearsOfWarQuerySqlServerTest.cs

+14
Original file line numberDiff line numberDiff line change
@@ -6106,6 +6106,20 @@ public override async Task Coalesce_with_non_root_evaluatable_Convert(bool async
61066106
""");
61076107
}
61086108

6109+
public override async Task Coalesce_with_non_root_evaluatable_Convert(bool async)
6110+
{
6111+
await base.Coalesce_with_non_root_evaluatable_Convert(async);
6112+
6113+
AssertSql(
6114+
"""
6115+
@__rank_0='1' (Nullable = true)
6116+
6117+
SELECT [g].[Nickname], [g].[SquadId], [g].[AssignedCityName], [g].[CityOfBirthName], [g].[Discriminator], [g].[FullName], [g].[HasSoulPatch], [g].[LeaderNickname], [g].[LeaderSquadId], [g].[PeriodEnd], [g].[PeriodStart], [g].[Rank]
6118+
FROM [Gears] FOR SYSTEM_TIME AS OF '2010-01-01T00:00:00.0000000' AS [g]
6119+
WHERE @__rank_0 = [g].[Rank]
6120+
""");
6121+
}
6122+
61096123
public override async Task Comparison_with_value_converted_subclass(bool async)
61106124
{
61116125
await base.Comparison_with_value_converted_subclass(async);

Diff for: test/EFCore.Sqlite.FunctionalTests/Query/GearsOfWarQuerySqliteTest.cs

+14
Original file line numberDiff line numberDiff line change
@@ -5468,6 +5468,20 @@ public override async Task Coalesce_with_non_root_evaluatable_Convert(bool async
54685468
""");
54695469
}
54705470

5471+
public override async Task Coalesce_with_non_root_evaluatable_Convert(bool async)
5472+
{
5473+
await base.Coalesce_with_non_root_evaluatable_Convert(async);
5474+
5475+
AssertSql(
5476+
"""
5477+
@__rank_0='1' (Nullable = true)
5478+
5479+
SELECT "g"."Nickname", "g"."SquadId", "g"."AssignedCityName", "g"."CityOfBirthName", "g"."Discriminator", "g"."FullName", "g"."HasSoulPatch", "g"."LeaderNickname", "g"."LeaderSquadId", "g"."Rank"
5480+
FROM "Gears" AS "g"
5481+
WHERE @__rank_0 = "g"."Rank"
5482+
""");
5483+
}
5484+
54715485
public override async Task Correlated_collections_with_Take(bool async)
54725486
{
54735487
await base.Correlated_collections_with_Take(async);

Diff for: test/EFCore.Tests/Metadata/Internal/EntityTypeTest.BaseType.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -677,7 +677,7 @@ public void Navigations_on_base_type_should_be_inherited()
677677
var specialCustomerType = model.AddEntityType(typeof(SpecialCustomer));
678678

679679
Assert.Equal(new[] { "Orders" }, customerType.GetNavigations().Select(p => p.Name).ToArray());
680-
Assert.Equal([], specialCustomerType.GetNavigations().Select(p => p.Name).ToArray());
680+
Assert.Equal(new string[0], specialCustomerType.GetNavigations().Select(p => p.Name).ToArray());
681681

682682
specialCustomerType.BaseType = customerType;
683683

Diff for: test/EFCore.Tests/Storage/ValueConversion/BytesToStringConverterTest.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public void Can_convert_bytes_to_strings()
2323
var converter = _bytesToStringConverter.ConvertFromProviderExpression.Compile();
2424

2525
Assert.Equal(new byte[] { 83, 112, 196, 177, 110, 204, 136, 97, 108, 32, 84, 97, 112 }, converter("U3DEsW7MiGFsIFRhcA=="));
26-
Assert.Equal([], converter(""));
26+
Assert.Equal(new byte[0], converter(""));
2727
}
2828

2929
[ConditionalFact]

Diff for: test/EFCore.Tests/Storage/ValueConversion/StringToBytesConverterTest.cs

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public void Can_convert_strings_to_UTF8()
1313
var converter = _stringToUtf8Converter.ConvertToProviderExpression.Compile();
1414

1515
Assert.Equal(new byte[] { 83, 112, 196, 177, 110, 204, 136, 97, 108, 32, 84, 97, 112 }, converter("Spın̈al Tap"));
16-
Assert.Equal([], converter(""));
16+
Assert.Equal(new byte[0], converter(""));
1717
}
1818

1919
[ConditionalFact]

0 commit comments

Comments
 (0)