实体框架核心RC2表名称复数化

时间:2016-05-27 22:23:41

标签: c# entity-framework-core pluralize tablename

有没有办法在EF Core RC 2中执行此代码的操作?

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

8 个答案:

答案 0 :(得分:75)

EF RC2版本没有这个惯例。这来自EF Core团队:

  

在过去的EF Core预发行版中,实体的表名是   与实体类名称相同。在RC2中,我们现在使用DbSet的名称   属性。如果没有为给定的实体类型定义DbSet属性,   然后使用实体类名称。


现在,如果您想恢复到表的RC1命名约定,您有3种方法可以使用:


1。为DbSet属性选择奇异名称:

一种方法是单独化你的DbSet属性名称(我不喜欢)。比如你有一个 Book 实体,你想要映射到 Book 表:

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


2。使用ToTable()Fluent API:

当然,您总是可以使用流畅的API来覆盖任何适当的约定,并根据您的需要指定表名:

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


第3。编写自定义约定:

仅仅因为EF Core RC2没有这方面的约定,这并不意味着我们不能自己编写。为此,首先我们需要在ModelBuilder对象上创建一个扩展方法:

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

然后我们只需从 DbContext 对象上的 OnModelCreating 方法调用它:

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


关闭时:

我不喜欢复数表格名称,我比其他选项更喜欢最后一个选项并继续使用。也就是说,这是我的个人意见,其他开发者可能会发现这三种方式中的任何一种都比其他方式更优惠,并选择与之相配:)

答案 1 :(得分:13)

对于EF Core 3.0,使用它来设置TableName属性(因为entity.Relational()不再存在):

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

答案 2 :(得分:8)

EF Core版似乎不支持entity.DisplayName。这是一个可行的替代方案:

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

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

答案 3 :(得分:2)

在Entity Framework NET核心v2中,您可以选择复数或用钩子单独化DbSetsCollections

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

有关详细信息,请参阅此答案:https://stackoverflow.com/a/47410837/869033

答案 4 :(得分:2)

EF Core 5 已解决在更新数据库上下文时使用开关“-NoPluralize”:

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

答案 5 :(得分:0)

这也是一个选择:

 using System.ComponentModel.DataAnnotations.Schema;

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

尽管您需要在每个实体上对其进行注释

答案 6 :(得分:0)

尽管[Table("some_table_name")]是内部类,但我在EF Core 3.1中使用它来保留实体类型上的ConventionAnnotation注释。

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

答案 7 :(得分:0)

我添加了一个虚拟

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

TableNames.FirstOrDefault();