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,在此处记录:
没有太多示例可以显示如何实现与以前相同的行为。关于如何消除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)
如果有人想在 .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
这是@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)
您可以使用完全相同的代码。Relational()是在assembly内部的类中定义的扩展方法,因此请确保您正在引用它。RelationalMetadataExtensionsMicrosoft.EntityFrameworkCore.Relational.dll
怎么样IPluralizer,你可以从它只是一个链接看到多元化挂钩的DbContext脚手架,从数据库即实体类生成,用于singularize实体类型名称和以复数DbSet名。它不用于表名生成。默认表名约定在文档的“ 表映射”部分中说明:
按照约定,将设置每个实体以映射到与
DbSet<TEntity>在派生上下文中公开该实体的属性同名的表。如果DbSet<TEntity>给定实体不包括,则使用类名。