Entity Framework Core RC2 table name pluralization

随声附和 提交于 2019-11-28 19:11:14
Morteza Manavi

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 :)

Nullius

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;
}

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

This is also an option:

 using System.ComponentModel.DataAnnotations.Schema;

 [Table("Book")]
 public class Book
 {...}

although you need to annotate it on each entity

For EF Core 3.0, 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())
        {
            entity.SetTableName(entity.DisplayName());
        }
    }
}
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!