【问题标题】:Entity Framework Core RC2 table name pluralizationEntity Framework Core RC2 表名复数
【发布时间】:2016-09-26 08:39:52
【问题描述】:

有没有办法完成这段代码在 EF Core RC 2 中所做的事情?

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

【问题讨论】:

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


    【解决方案1】:

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

    您当然可以始终使用 fluent 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();
    }
    


    结束时:

    我不喜欢复数表名,而且我比其他选项更喜欢最后一个选项,并同意了。也就是说,这是我个人的意见,其他开发人员可能会发现这 3 种方式中的任何一种都比其他方式更有利,并选择采用它:)

    【讨论】:

    • 谢谢莫特萨。我认为现在我只需在实体上设置表名。
    • @Tančev Saša 我试图在base.OnModelCreating(builder); 之前调用modelBuilder.RemovePluralizingTableNameConvention(); 并且身份表的名称正常
    • IMutableEntityType 没有 Relational() 方法,是不是改了?
    • entity.Relational().TableName = entity.DisplayName();不适用于 .net core 3
    • 你应该可以使用 entity.SetTableName(entity.DisplayName());
    【解决方案2】:

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

    【讨论】:

    • 如果您将此方法用于继承的实体,您将收到错误...Only base type entity types can be mapped to a table.。为了解决这个问题,我使用了条件if (entity.BaseType == null)。基类将返回null,而继承的类显然会返回基类型。
    • @Métoule : 调用 modelBuilder.RemovePluralizingTableNameConvention()entity.ToView("MyView") 结合使用时会出现问题:实体随后被标记为表格而不是视图。
    • @Métoule 请检查 EF Core 5 的可能问题和解决方法stackoverflow.com/a/65585664/1769622
    • .NET 6 怎么样? .NET 6 中既不存在 entity.Relational() 也不存在 entity.SetTableName()。
    • @Creative: entity.SetTableName 存在于 EF Core 6 中。
    【解决方案3】:

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

    【讨论】:

    • entity.DisplayNameMicrosoft.EntityFrameworkCore.Metadata.Internal 命名空间(实际上是公共的,而不是internal)中的扩展方法。
    【解决方案4】:

    这也是一种选择:

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

    虽然您需要在每个实体上对其进行注释

    【讨论】:

    • 我发现自己想通过模式进行组织,所以无论如何我在每个类上都使用这个标签进行注释。举个例子:[Table("Book", Schema = "library")]
    【解决方案5】:

    在 Entity Framework NET core v2 中,您可以选择 pluralize 或使用钩子将 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

    【讨论】:

      【解决方案6】:

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

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

      【讨论】:

      • 应该是--no-pluralize
      【解决方案7】:

      我在 EF Core 3.1 中使用它来保留实体类型上的 [Table("some_table_name")] 注释,尽管 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);
              }
          }
      }
      

      【讨论】:

        【解决方案8】:

        我添加了一个虚拟

        public virtual DbSet<TableName> TableName{ get; set; }
        public DbSet<TableName> TableNames { get; set; }
        
        TableNames.FirstOrDefault();
        

        【讨论】:

          猜你喜欢
          • 2017-01-09
          • 1970-01-01
          • 2019-02-23
          • 2020-11-27
          • 2017-02-17
          • 2022-12-10
          • 2022-01-19
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多