首页 > 解决方案 > 在实体框架核心中一起实现奇异命名约定和数据注释的正确方法

问题描述

我正在使用Entity Framework Core 2.2并且所有数据库表名都是单数的,所以我在 方法中使用overriding复数命名约定OnModelCreating

 protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            foreach (IMutableEntityType entityType in modelBuilder.Model.GetEntityTypes())
            {
                entityType.Relational().TableName = entityType.DisplayName();
            }
        }

但是在某些情况下,实体名称与表名称不同,例如

[Table("AzureSchemaVersionExecutionExtract", Schema = "dbo")]
    public class AzureDataExtract
    {
        public int Id { get; set; }
        public DateTime  DateApplied { get; set; }
    }

当我运行该项目时,它会抱怨它找不到表AzureDataExtract,所以我在方法中添加了以下代码OnModelCreating并且它可以工作。我需要知道这是实施Data AnnotationsSingular Naming Convention一起的正确方法

protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            foreach (IMutableEntityType entityType in modelBuilder.Model.GetEntityTypes())
            {
                entityType.Relational().TableName = entityType.DisplayName();
            }
            modelBuilder.Entity<AzureDataExtract>().ToTable("AzureSchemaVersionExecutionExtract","dbo");
        }

标签: c#entity-framework-core

解决方案


这是可能的,但不能使用公共 API。但是您已经在使用Microsoft.EntityFrameworkCore.Metadata.Internal命名空间中的方法,所以这应该不是问题 - 只需检查升级到较新的 EF Core 版本时是否发生了某些变化并相应地更新。

在 EF Core 2.2 中,诀窍是使用内部Relational()方法 acceptConfigurationSource和 pass ConfigurationSource.Convention。数据注释和常规流式 API 具有更高的优先级,因此这只会覆盖使用该DbSet名称的内部 EF Core 表名称约定。

foreach (var entityType in modelBuilder.Model.GetEntityTypes().Where(t => !t.IsOwned())
{
    entityType.AsEntityType().Builder.Relational(ConfigurationSource.Convention)
        .ToTable(entityType.DisplayName());
}

推荐阅读