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

Pau*_*nza 32 c# pluralize tablename entity-framework-core

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

protected override void OnModelCreating(ModelBuilder modelBuilder)
{    
    modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
Run Code Online (Sandbox Code Playgroud)

Mor*_*avi 86

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

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


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


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

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

public DbSet<Book> Book { get; set; }
Run Code Online (Sandbox Code Playgroud)


2.使用ToTable()Fluent API:

当然,您总是可以使用流畅的API来覆盖任何适当的约定,并将表名指定为您想要的任何内容:

modelBuilder.Entity<Book>().ToTable("Book");
Run Code Online (Sandbox Code Playgroud)


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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

然后我们简单地从DbContext对象上的OnModelCreating方法调用它:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.RemovePluralizingTableNameConvention();
}
Run Code Online (Sandbox Code Playgroud)


关闭时:

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

  • 您应该能够使用entity.SetTableName(entity.DisplayName()); (5认同)
  • 实体.Relational().TableName = 实体.DisplayName(); 不适用于.net core 3 (4认同)
  • @Tančev Saša 我试图在 `base.OnModelCreating(builder);` 之前调用 `modelBuilder.RemovePluralizingTableNameConvention();` 并且身份表具有确定的名称 (3认同)
  • IMutableEntityType 没有 Relational() 方法,是不是变了? (3认同)

Nul*_*ius 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;
}
Run Code Online (Sandbox Code Playgroud)

  • “ entity.DisplayName”是“ Microsoft.EntityFrameworkCore.Metadata.Internal”命名空间中的扩展方法(实际上是公共的,而不是“内部”)。 (3认同)

Mét*_*ule 8

对于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());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 如果将此方法与继承的实体一起使用,您将收到错误“...只有基本类型实体类型可以映射到表。”。为了解决这个问题,我使用了条件“if (entity.BaseType == null)”。基类将返回“null”,而继承类显然将返回基类型。 (2认同)

sjo*_*urg 6

这也是一种选择:

 using System.ComponentModel.DataAnnotations.Schema;

 [Table("Book")]
 public class Book
 {...}
Run Code Online (Sandbox Code Playgroud)

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


Son*_*u K 6

EF Core 5 已解决在更新 Db 上下文时使用开关“-NoPluralize”的问题:

Scaffold-DbContext "..conn str.." Microsoft.EntityFrameworkCore.SqlServer -OutputDir EntityDbContext -Project DoctorsExpress.Domain -Force -NoPluralize
Run Code Online (Sandbox Code Playgroud)


Nic*_* N. 5

在 Entity Framework NET core v2 中,您可以选择复数或单数DbSets并Collections使用钩子。

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;
    }
}
Run Code Online (Sandbox Code Playgroud)

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