Adam Wojnar
Adam Wojnar

Reputation: 545

Can EFCore Scaffold-DbContext generate custom Model names?

I'm using EFCore 3.0 with Database-first approach and was wondering about how Model names are generated. First of all, I'm using -DataAnnotations and -Force switches and the command looks like that:

Scaffold-DbContext "data source=foo;initial catalog=bar;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework;Connection Timeout=300;Application Name=FooBar" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Entities/Bar -ContextDir DbContexts -Context BarContext -Tables "Cars", "Makes", "Types" -DataAnnotations -Force

Scaffold-DbContext creates C# models exactly with the sames as tables in the database. So It will create 3 classes: Cars.cs, Makes.cs and Types.cs.

My question is: can we customize these names? Can I generate class Auto.cs instead of Cars.cs??

This task looks very trival, because from the human perspective it is this algorithm:

  1. Run Scaffold-DbContext

  2. Refactor-rename Cars.cs class to Auto.cs

  3. Done. Final result:

    [Table("cars")]
    public partial class Auto
    {
        public Auto()
        {
        }
    
    }
    

So if the answer to my first question is "No". My follow up question is: Can we somehow automate it? It's really not a complicated task. If we change the command line to something like:

-Tables "Cars" as "Auto", "Makes" as "Make", "Types" as "Type

Is there a way to change/override Scaffold-DbContext command? Has anyone done that? Thanks!

Upvotes: 2

Views: 10549

Answers (2)

John Cummings
John Cummings

Reputation: 2184

There isn't really a straightforward way to choose custom names. There is, however, a way to control pluralizing and "singularizing." Something similar to this code might provide a hacky way to do what you want (untested):

using Microsoft.EntityFrameworkCore.Design;
using Microsoft.Extensions.DependencyInjection;

/// <summary>
/// How EF should make class and set name(s) plural or singular 
/// </summary>
/// <see cref="https://stackoverflow.com/a/47410837/1518546"/>
/// <seealso cref="https://learn.microsoft.com/en-us/ef/core/what-is-new/ef-core-3.x/breaking-changes#microsoftentityframeworkcoredesign-is-now-a-developmentdependency-package"/>
public class EFPluralizer : IPluralizer
{
    Dictionary<string, string> SingularToPlural = new(StringComparer.OrdinalIgnoreCase)
    {
        { "Car", "Auto" },
        { "Make", "Make" },
        { "Type", "Type" },
    };
    Dictionary<string, string> PluralToSingular = new(StringComparer.OrdinalIgnoreCase)
    {
        { "Cars", "Auto" },
        { "Makes", "Make" },
        { "Types", "Type" },
    };

    public string Pluralize(string name)
    {

        // In a nullability context, the out paramater should be `string?`
        if (SingularToPlural.TryGetValue(name, out string value))
        {
            return value;
        }
        return name;
    }

    public string Singularize(string name)
    {

        // In a nullability context, the out paramater should be `string?`
        if (PluralToSingular.TryGetValue(name, out string? value))
        {
            return value;
        }
        // see if the values in the SingularToPlural have a match
        var kv = SingularToPlural.FirstOrDefault(kv => kv.Value.Equals(name, StringComparison.OrdinalIgnoreCase));
        return kv.Key ?? name;
    }

Don't forget the AddSingleton call toward the bottom of the code above.

Upvotes: 1

Kalyani Analytics
Kalyani Analytics

Reputation: 1

use -NoPluralize, like this:

Scaffold-DbContext "data source=foo;initial catalog=bar;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework;Connection Timeout=300;Application Name=FooBar" Microsoft.EntityFrameworkCore.SqlServer -OutputDir Entities/Bar -ContextDir DbContexts -Context BarContext -Tables "Cars", "Makes", "Types" -DataAnnotations -Force -NoPluralize

Upvotes: -3

Related Questions