Repository navigation
Pascal-case the DbContext name when scaffolding #27886
Description
Activity
@vanillajonathan The filename should not have any impact here. Instead, the database name defined in the SQLite database is being used for the context name. As you state, the context name can be specified if you want something different, including different casing. Beyond that templates (#4038) will allow this to be changed if you choose.
vanillajonathan commented
on Apr 26, 2022 ContributorAuthorMore actionsAh, I see.
Perhaps it should always use uppercase the first letter of the filename and the class name regardless of the name defined in the SQLite database?Nope, it actually does come directly from the file name. Technically, the database name is (almost) always
mainin SQLite. I agree that we should scrub these to make them more idiomatic to .NET.- addedgood first issueThis issue should be relatively straightforward to fix.This issue should be relatively straightforward to fix.
on Apr 28, 2022 Hey I have seen the label, may I try to work on this? @bricelam
Sure! It’s probably easiest to do it here:
efcore/src/EFCore.Design/Scaffolding/Internal/RelationalScaffoldingModelFactory.cs
Line 169 in 2272257
modelBuilder.Model.SetDatabaseName(databaseModel.DatabaseName); And use _candidateNamingService to clean up the name when _options.UseDatabaseNames is
truefalse.But you might also be able to do it here: 🤷♂️
? _code.Identifier(annotatedName + DbContextSuffix) …or here:
efcore/src/EFCore.Sqlite.Core/Scaffolding/Internal/SqliteDatabaseModelFactory.cs
Line 123 in 2272257
var name = Path.GetFileNameWithoutExtension(connection.DataSource); Thanks for your suggestion @bricelam!
Do you think could be a good idea to keep the file name as input or is it better to pick up the database name instead?
In case you prefer the first option, if this problem is only related to SQLite, I would go for the file SqliteDatabaseModelFactory.cs since it's in the project EFCore.Sqlite.Core and not in EFCore.Design:
efcore/src/EFCore.Sqlite.Core/Scaffolding/Internal/SqliteDatabaseModelFactory.cs
Line 123 in 2272257
var name = Path.GetFileNameWithoutExtension(connection.DataSource); My approach would be to capitalize the first letter (of the value) of the variable called
name.To achieve this, I would do something like:
private static string GetDatabaseName(string? str) { var name = Path.GetFileNameWithoutExtension(str); if (!string.IsNullOrEmpty(name)) { //name = char.ToUpper(name[0]) + name.Substring(1); name = char.ToUpper(name[0]) + name[1..]; } if (string.IsNullOrEmpty(name)) { name = "Main"; } return name; }
Do you think is better to create a method for capitalization? If so, where?
I don't see this issue being specific to SQLite. If a SQL Server database was named blogging, it would also generate bloggingContext. So it probably shouldn't be fixed just inside SqliteDatabaseModelFactory.
The
CandidateNamingService.GenerateCandidateIdentifiermethod has logic to transform strings into Pascal case--it capitalizes the first letter of each word and remove things like underscores and hyphens. I'd reuse that.Reacted by Arthur Vickers, Daniele Maltese and Jonathan- changed the title
[-]Scaffolding creates lowercase DbContext[/-][+]Pascal-case the DbContext name when scaffolding[/+]on Jun 23, 2022
When scaffolding from a SQLite database using the
dotnet eftool it will create the DbContext with the initial lowercase if the database filename is lowercase.Example:
It creates the
DbContextwith the filenamebloggingContext.csand the class namebloggingContextwhich is rather ugly.Running
dotnet ef dbcontext scaffold --helpit states:But my expectation was that it would still create the filename and the class name with the initial letter uppercase as is the .NET convention.
EF Core version: 6.0.4
Database provider: (e.g. Microsoft.EntityFrameworkCore.Sqlite)
Target framework: (e.g. .NET 6.0)