c# - 在实体框架核心中一起实现奇异命名约定和数据注释的正确方法
问题描述
我正在使用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 Annotations
和Singular 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");
}
解决方案
这是可能的,但不能使用公共 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());
}