EF Core 3 supports pluralization by convention, and allows you to enable and customize it. This blog post will show you how!

When pluralization is enabled, you will by convention get pluralized DbSet and navigation property names:

public partial class ChinookContext : DbContext
{
    public DbSet<Album> Albums { get; set; }
}

public partial class Album
{
    public ICollection<Track> Tracks { get; set; }
}

If you have plural table names in your legacy database, their entity class names will be singularized: dbo.Albums => class Album

Pluralization with the EF Core command line tools

If you are using the EF Core console command dotnet ef dbcontext scaffold or Package Manager Console in Visual Studio Scaffold-DbContext, you can hook up pluralization via code in your project.

First you must add a reference to the Microsoft.EntityFrameworkCore.Design package from your startup project.

Then add class that implements the IPluralizer interface, for example an implementation that uses the Humanizer.Core pluralization component:

using Humanizer;
using Microsoft.EntityFrameworkCore.Design;

public class HumanizerPluralizer : IPluralizer
{
    public string Pluralize(string name)
        => name?.Pluralize(inputIsKnownToBeSingular: false);

    public string Singularize(string name)
        => name?.Singularize(inputIsKnownToBePlural: false);
}

Then add a class that inherits from IDesignTimeServices, in order to replace the built-in services with your own implementation.

class CustomDesignTimeServices : IDesignTimeServices
{
    public void ConfigureDesignTimeServices(IServiceCollection services)
        => services.AddSingleton<IPluralizer, HumanizerPluralizer>();
}

The built-in design time services uses a pluralizer implementation that does nothing, but maybe EF Core will use Humanizer.Core by default in a future release.

If you would like pluralization to resemble the pluralization generated by EF6, then Brice Lambson from the EF Core team has published a pluralizer NuGet package, that implements the pluralizer used by EF6. This package also demonstrates the ability for a NuGet package to register/inject EF Core design-time services during build.

Finally, run the scaffolding command, that will now take advantage of your efforts above.

Command line:

dotnet ef dbcontext scaffold "Data Source=.;Initial Catalog=Chinook;Integrated Security=true" Microsoft.EntityFrameworkCore.SqlServer

Package Manager Console:

Scaffold-DbContext 'Data Source=.;Initial Catalog=Chinook;Integrated Security=true' Microsoft.EntityFrameworkCore.SqlServer

An advantage of implementing your custom pluralizer, is that you can override/fix potential issue with any third party pluralizer library. Also, you can opt in to use non-English pluralization.

Pluralization with EF Core Power Tools

Pluralize or singularize generated object names (English).

This will enable Humanzier.Core for pluralization. If you want to use the EF6 pluralizer (for better backward compatibility with existing code), you can do so, as described here

Using EF Core Power Tools will not require you to add any design code or NuGet packages to your project.

Thanks to @bricelam for inspiration!

Comments or questions?