Entity Framework Core RC2 table name pluralization

C#Entity Framework-CorePluralizeTablename

C# Problem Overview


Is there a way to do what this code did in EF Core RC 2?

protected override void OnModelCreating(ModelBuilder modelBuilder)
{    
    modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}

C# Solutions


Solution 1 - C#

There is no convention for this as of EF RC2 build. This is from EF Core team: > In past pre-release of EF Core, the table name for an entity was the > same as the entity class name. In RC2 we now use the name of the DbSet > property. If no DbSet property is defined for the given entity type, > then the entity class name is used.


Now if you want to revert back to the RC1 naming conventions for tables, you have 3 ways to go with:


1. Choosing Singular Names for DbSet Properties:

One way is to singularize your DbSet property names (which I don't like). Say for example you have a Book entity and you want to map to a Book table:

public DbSet<Book> Book { get; set; }


2. Using ToTable() Fluent API:

You can of course always use fluent API to override any convention in place and dictate the table name to whatever you want:

modelBuilder.Entity<Book>().ToTable("Book");


3. Writing a Custom Convention:

Just because EF Core RC2 does not have a convention for this, it doesn't mean we can't write our own. To do so, first we need to create an extension method on ModelBuilder object:

using Microsoft.EntityFrameworkCore.Metadata.Internal;

public static class ModelBuilderExtensions 
{
    public static void RemovePluralizingTableNameConvention(this ModelBuilder modelBuilder)
    {
        foreach (IMutableEntityType entity in modelBuilder.Model.GetEntityTypes())
        {
            entity.Relational().TableName = entity.DisplayName();
        }
    }
}

And then we simply call it from the OnModelCreating method on our DbContext object:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.RemovePluralizingTableNameConvention();
}


On Closing:

I don't like plural table names and I like the last option better than the others and went with that. That said, it's my personal opinion and other developers might find any of these 3 ways more favorable than the others and choose to go with that :)

Solution 2 - C#

For EF Core 3.0 and above, use this to set the TableName property (because entity.Relational() no longer exist):

public static class ModelBuilderExtensions 
{
    public static void RemovePluralizingTableNameConvention(this ModelBuilder modelBuilder)
    {
        foreach (IMutableEntityType entity in modelBuilder.Model.GetEntityTypes())
        {
            if (entityType.BaseType == null)
            {
                entity.SetTableName(entity.DisplayName());
            }
        }
    }
}

Solution 3 - C#

The EF Core version doesn't seem to support entity.DisplayName. This is a working alternative:

foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
    // Skip shadow types
    if (entityType.ClrType == null)
        continue;

    entityType.Relational().TableName = entityType.ClrType.Name;
}

Solution 4 - C#

This is also an option:

 using System.ComponentModel.DataAnnotations.Schema;
 
 [Table("Book")]
 public class Book
 {...}

although you need to annotate it on each entity

Solution 5 - C#

In Entity Framework NET core v2 you can choose to pluralize or singularize DbSets and Collections with a hook.

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

public class MyPluralizer : IPluralizer
{
    public string Pluralize(string name)
    {
        return Inflector.Inflector.Pluralize(name) ?? name;
    }

    public string Singularize(string name)
    {
        return Inflector.Inflector.Singularize(name) ?? name;
    }
}

See this answer for more information: https://stackoverflow.com/a/47410837/869033

Solution 6 - C#

The EF Core 5 has resolved using a switch "-NoPluralize" while updating the Db Context:

Scaffold-DbContext "..conn str.." Microsoft.EntityFrameworkCore.SqlServer -OutputDir EntityDbContext -Project DoctorsExpress.Domain -Force -NoPluralize

Solution 7 - C#

I use this for EF Core 3.1 to preserve [Table("some_table_name")] annotation on entity types, although ConventionAnnotation is an internal class.

static class UseEntityTypeNameForTableNameExtension
{
    public static void UseEntityTypeNameForTableName(this ModelBuilder modelBuilder)
    {
        foreach (var entity in modelBuilder.Model.GetEntityTypes())
        {
            var tableNameAnnotation = (ConventionAnnotation)entity.FindAnnotation(RelationalAnnotationNames.TableName);
#pragma warning disable EF1001
            var configurationSource = tableNameAnnotation.GetConfigurationSource();
#pragma warning restore EF1001
            if (configurationSource != ConfigurationSource.Convention)
            {
                // Set explicitly using Fluent API or has TableAttribute DataAnnotation
                continue;
            }
            var defaultTableName = entity.GetDefaultTableName();
            entity.SetTableName(defaultTableName);
        }
    }
}

Solution 8 - C#

I went with adding a virtual

public virtual DbSet<TableName> TableName{ get; set; }
public DbSet<TableName> TableNames { get; set; }

TableNames.FirstOrDefault();

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionPaul SperanzaView Question on Stackoverflow
Solution 1 - C#Morteza ManaviView Answer on Stackoverflow
Solution 2 - C#MétouleView Answer on Stackoverflow
Solution 3 - C#NulliusView Answer on Stackoverflow
Solution 4 - C#Sjors MiltenburgView Answer on Stackoverflow
Solution 5 - C#Nick N.View Answer on Stackoverflow
Solution 6 - C#Sonu KView Answer on Stackoverflow
Solution 7 - C#SeongChan LeeView Answer on Stackoverflow
Solution 8 - C#notElonMuskView Answer on Stackoverflow