Skip to content

Commit 18fc1d0

Browse files
committed
Set the environment when executing Scaffold-DBContext
Fixes #35641
1 parent 4623a39 commit 18fc1d0

File tree

10 files changed

+103
-77
lines changed

10 files changed

+103
-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+
[SqlServerConfiguredCondition]
20+
public void ScaffoldContext_throws_exceptions_for_invalid_context_name()
21+
{
22+
ValidateContextNameInReverseEngineerGenerator("Invalid!CSharp*Class&Name");
23+
ValidateContextNameInReverseEngineerGenerator("1CSharpClassNameCannotStartWithNumber");
24+
ValidateContextNameInReverseEngineerGenerator("volatile");
25+
}
26+
27+
private void ValidateContextNameInReverseEngineerGenerator(string contextName)
28+
{
29+
var operations = CreateOperations([]);
30+
31+
Assert.Equal(
32+
DesignStrings.ContextClassNotValidCSharpIdentifier(contextName),
33+
Assert.Throws<ArgumentException>(
34+
() => operations.ScaffoldContext(
35+
"Microsoft.EntityFrameworkCore.SqlServer",
36+
"connectionstring",
37+
"",
38+
"",
39+
dbContextClassName: contextName,
40+
null,
41+
null,
42+
"FakeNamespace",
43+
contextNamespace: null,
44+
useDataAnnotations: false,
45+
overwriteFiles: true,
46+
useDatabaseNames: false,
47+
suppressOnConfiguring: true,
48+
noPluralize: false))
49+
.Message);
50+
}
51+
52+
[ConditionalFact]
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.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)