在EF Core 2中使用单表名称

Ada*_*dam 5 c# ef-code-first entity-framework-core

我希望我的域名类名称与我的数据库表名称相匹配(无复数形式)。

在EF Core 1.1中,我使用以下代码来做到这一点:

public static void RemovePluralisingTableNameConvention(this ModelBuilder modelBuilder)
{
    foreach (IMutableEntityType entityType in modelBuilder.Model.GetEntityTypes())
    {
        entityType.Relational().TableName = entityType.DisplayName();
    }
}
Run Code Online (Sandbox Code Playgroud)

在EF Core 2.0中,此代码无法编译,因为Relational()它不是IMutableEntityType上的方法。无论如何,在EF Core 2.0中,他们添加了IPluralizer,在此处记录:

https://github.com/aspnet/EntityFramework.Docs/blob/master/entity-framework/core/what-is-new/index.md#pluralization-hook-for-dbcontext-scaffolding

没有太多示例可以显示如何实现与以前相同的行为。关于如何消除EF Core 2中的多元化的任何线索?

nat*_*ate 12

您可以这样做,而无需使用内部 EF API 调用 ClrType.Name

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    foreach (var entityType in modelBuilder.Model.GetEntityTypes())
    {
        // Use the entity name instead of the Context.DbSet<T> name
        // refs https://docs.microsoft.com/en-us/ef/core/modeling/entity-types?tabs=fluent-api#table-name
        modelBuilder.Entity(entityType.ClrType).ToTable(entityType.ClrType.Name);
    }
}
Run Code Online (Sandbox Code Playgroud)


Vik*_*ini 8

如果有人想在 .NET Core 3.1 中尝试,您可以将扩展方法构建为

public static class ModelBuilderExtension
{
    /// <summary>
    /// Remove pluralizing table name convention to create table name in singular form.
    /// </summary>       
    public static void RemovePluralizingTableNameConvention(this ModelBuilder modelBuilder)
    {
        foreach (IMutableEntityType entityType in modelBuilder.Model.GetEntityTypes())
        {
            entityType.SetTableName(entityType.DisplayName());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

确保安装依赖包: Microsoft.EntityFrameworkCore.Relational


Seb*_*idz 7

这是@Vicram 答案的扩展。我在EF Core 5中应用了它

modelBuilder.Model.GetEntityTypes()            
    .Configure(e => e.SetTableName(e.DisplayName()));
Run Code Online (Sandbox Code Playgroud)

但是,如果您的域中有值对象,它们将全部被视为实体类型并在数据库中创建为表。如果您的值对象都继承自基类型,ValueObject您可以使用以下内容:

modelBuilder.Model.GetEntityTypes()            
    .Where(x => !x.ClrType.IsSubclassOf(typeof(ValueObject)))
    .Configure(e => e.SetTableName(e.DisplayName()));
Run Code Online (Sandbox Code Playgroud)

我没有检查过其他 EF 核心版本,但版本 5 肯定是这样。

EF Core 5 中的另一个缺点是,当您在实体模型中使用继承时,设置表名称将从Table-per-Hierarchy (TPH) 更改为Table-per-Type (TPT)

您可以使用以下替代方案(假设您的实体派生自BaseEntity类)

modelBuilder.Model.GetEntityTypes()
    .Where(x => x.ClrType.BaseType == typeof(BaseEntity))
    .Configure(e => e.SetTableName(e.DisplayName()));
Run Code Online (Sandbox Code Playgroud)

Configure扩展名在哪里

public static class ModelBuilderExtensions
{
    public static void Configure(this IEnumerable<IMutableEntityType> entityTypes, Action<IMutableEntityType> convention)
    {
        foreach (var entityType in entityTypes)
        {
            convention(entityType);
        }
    }

    public static void Configure(this IEnumerable<IMutableProperty> propertyTypes, Action<IMutableProperty> convention)
    {
        foreach (var propertyType in propertyTypes)
        {
            convention(propertyType);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Iva*_*oev 5

您可以使用完全相同的代码。Relational()是在assembly内部的类中定义的扩展方法,因此请确保您正在引用它。RelationalMetadataExtensionsMicrosoft.EntityFrameworkCore.Relational.dll

怎么样IPluralizer,你可以从它只是一个链接看到多元化挂钩的DbContext脚手架,从数据库即实体类生成,用于singularize实体类型名称和以复数DbSet名。它不用于表名生成。默认表名约定在文档的“ 表映射”部分中说明:

按照约定,将设置每个实体以映射到与DbSet<TEntity>在派生上下文中公开该实体的属性同名的表。如果DbSet<TEntity>给定实体不包括,则使用类名。