Skip to content

Commit 5a759d5

Browse files
authored
Capitalize database name (#27966)
When scaffolding from a database the database name is modified in order to respect .NET conventions #Fixes 27886
1 parent 5887391 commit 5a759d5

File tree

4 files changed

+49
-2
lines changed

4 files changed

+49
-2
lines changed

src/EFCore.Design/Scaffolding/Internal/CandidateNamingService.cs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,13 @@ public virtual string GetPrincipalEndCandidateNavigationPropertyName(
6565
: foreignKey.DeclaringEntityType.ShortName();
6666
}
6767

68-
private static string GenerateCandidateIdentifier(string originalIdentifier)
68+
/// <summary>
69+
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
70+
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
71+
/// any release. You should only use it directly in your code with extreme caution and knowing that
72+
/// doing so can result in application failures when updating to a new Entity Framework Core release.
73+
/// </summary>
74+
public virtual string GenerateCandidateIdentifier(string originalIdentifier)
6975
{
7076
var candidateStringBuilder = new StringBuilder();
7177
var previousLetterCharInWordIsLowerCase = false;

src/EFCore.Design/Scaffolding/Internal/ICandidateNamingService.cs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,15 @@ public interface ICandidateNamingService
2929
/// </summary>
3030
string GenerateCandidateIdentifier(DatabaseColumn originalColumn);
3131

32+
/// <summary>
33+
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
34+
/// the same compatibility standards as public APIs. It may be changed or removed without notice in
35+
/// any release. You should only use it directly in your code with extreme caution and knowing that
36+
/// doing so can result in application failures when updating to a new Entity Framework Core release.
37+
/// </summary>
38+
string GenerateCandidateIdentifier(string databaseName);
39+
40+
3241
/// <summary>
3342
/// This is an internal API that supports the Entity Framework Core infrastructure and not subject to
3443
/// the same compatibility standards as public APIs. It may be changed or removed without notice in

src/EFCore.Design/Scaffolding/Internal/RelationalScaffoldingModelFactory.cs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,10 @@ protected virtual ModelBuilder VisitDatabaseModel(ModelBuilder modelBuilder, Dat
166166

167167
if (!string.IsNullOrEmpty(databaseModel.DatabaseName))
168168
{
169-
modelBuilder.Model.SetDatabaseName(databaseModel.DatabaseName);
169+
modelBuilder.Model.SetDatabaseName(
170+
!_options.UseDatabaseNames && !string.IsNullOrEmpty(databaseModel.DatabaseName)
171+
? _candidateNamingService.GenerateCandidateIdentifier(databaseModel.DatabaseName)
172+
: databaseModel.DatabaseName);
170173
}
171174

172175
if (!string.IsNullOrEmpty(databaseModel.Collation))

test/EFCore.Design.Tests/Scaffolding/Internal/RelationalScaffoldingModelFactoryTest.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,14 @@ public RelationalScaffoldingModelFactoryTest()
5050
_reporter.Clear();
5151
}
5252

53+
[ConditionalFact]
54+
public void Capitalize_DatabaseName()
55+
{
56+
var database = new DatabaseModel { DatabaseName = "northwind" };
57+
var model = _factory.Create(database, new ModelReverseEngineerOptions { UseDatabaseNames = false });
58+
Assert.Equal("Northwind", model.GetDatabaseName());
59+
}
60+
5361
[ConditionalFact]
5462
public void Creates_entity_types()
5563
{
@@ -131,6 +139,27 @@ public void Creates_entity_types_case_insensitive()
131139
Assert.Equal(2, model.GetEntityTypes().Select(et => et.Name).Distinct(StringComparer.OrdinalIgnoreCase).Count());
132140
}
133141

142+
[ConditionalTheory]
143+
[InlineData("PascalCase")]
144+
[InlineData("camelCase")]
145+
[InlineData("snake-case")]
146+
[InlineData("MixedCASE")]
147+
[InlineData("separated_by_underscores")]
148+
[InlineData("PascalCase_withUnderscore")]
149+
[InlineData("ALL_CAPS")]
150+
[InlineData("numbers0Dont1Affect23Upper45Case678To9LowerCase10Boundary999")]
151+
[InlineData("We1!*~&%rdCh@r^act()0rs")]
152+
public void Get_DatabaseName(string expectedValue)
153+
{
154+
var options = new ModelReverseEngineerOptions { UseDatabaseNames = true };
155+
156+
var database = new DatabaseModel { DatabaseName = expectedValue };
157+
var model = _factory.Create(database, options);
158+
Assert.Equal(expectedValue, model.GetDatabaseName());
159+
160+
}
161+
162+
134163
[ConditionalFact]
135164
public void Loads_column_types()
136165
{

0 commit comments

Comments
 (0)