3

I am running the following command to scaffold C# models of an existing database:

dotnet ef dbcontext scaffold "<conn string>" Microsoft.EntityFrameworkCore.SqlServer

I would like to amend some of the automatic pluralizations as part of the run, instead of just reverting the change each time I run the command after a database schema change.

I have read other postings recommending using Bricelam's Pluralizer, but that is quite dated as we are using .NET 8 and would prefer not to use such an old version of .NET.

Is there a way to specify an IPluralizer (or similar) as part of the scaffold command?

1 Answer 1

3

Well, you can specify your implementation of IPluralizer in your project in which you want your DbContext scaffolded.

But there's a catch - this interface won't be visible unless you modify your csproj in following way:

<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.6">
  <!--<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>-->
  <PrivateAssets>all</PrivateAssets>
</PackageReference>

Note the commented out part. This makes IPluralizer visible - big thanks to this SO post

Then you just need to define implementations of interfaces:

public class CustomPluralizer : IPluralizer
{
    public string Pluralize(string name)
    {
        // Example: prevent pluralization for certain terms
        if (name.EndsWith("Data"))
            return name + "Neat"; // just for testing purposes

        // simple fallback (you can make it smarter later)
        return name + "s";
    }

    public string Singularize(string name)
    {
        if (name.EndsWith("Data"))
            return name + "Neat"; // just for testing purposes

        if (name.EndsWith("s"))
            return name.Substring(0, name.Length - 1);

        return name;
    }
}

public class DesignTimeServices : IDesignTimeServices
{
    public void ConfigureDesignTimeServices(IServiceCollection services)
    {
        services.AddSingleton<IPluralizer, CustomPluralizer>();
    }
}

Now this pluralizer will take effect when you do dotnet ef dbcontext scaffold

EDIT If you want to fallback to default behaviour, EF Core comes with Humanizer package and you can use it:

using Microsoft.EntityFrameworkCore.Design;
using Humanizer;

namespace consolecsharp;

public class CustomPluralizer : IPluralizer
{
    public string Pluralize(string name)
    {
        if (name.EndsWith("Data"))
            return name + "Neat"; // just for testing purposes

        return name.Pluralize();
    }

    public string Singularize(string name)
    {
        if (name.EndsWith("Data"))
            return name + "Neat"; // just for testing purposes

        return name.Singularize();
    }
}
Sign up to request clarification or add additional context in comments.

3 Comments

Thank you very much for this. I was very close to this solution but just didn't get everything quite right until I followed your post above. I'll keep digging, as I'm also wondering if there is a way to customize just certain problematic tables, but allow the default built-in pluralization to happen for all other tables. I'll follow-up here if I find a solution.
@RedPuffle Please see edit :)
This is great. It doesn't quite match perfectly what was there before. For instance, "Access" gets singularized to "Acces". But I can work around those issues. Thank you again for your excellent and speedy response.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.