Is there a way to do what this code did in EF Core RC 2?
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
Is there a way to do what this code did in EF Core RC 2?
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
There is no convention for this as of EF RC2 build. This is from EF Core team:
In past pre-release of EF Core, the table name for an entity was the same as the entity class name. In RC2 we now use the name of the DbSet property. If no DbSet property is defined for the given entity type, then the entity class name is used.
Now if you want to revert back to the RC1 naming conventions for tables, you have 3 ways to go with:
1. Choosing Singular Names for DbSet Properties:
One way is to singularize your DbSet property names (which I don't like). Say for example you have a Book entity and you want to map to a Book table:
public DbSet<Book> Book { get; set; }
2. Using ToTable() Fluent API:
You can of course always use fluent API to override any convention in place and dictate the table name to whatever you want:
modelBuilder.Entity<Book>().ToTable("Book");
3. Writing a Custom Convention:
Just because EF Core RC2 does not have a convention for this, it doesn't mean we can't write our own. To do so, first we need to create an extension method on ModelBuilder
object:
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();
}
}
}
And then we simply call it from the OnModelCreating method on our DbContext object:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.RemovePluralizingTableNameConvention();
}
On Closing:
I don't like plural table names and I like the last option better than the others and went with that. That said, it's my personal opinion and other developers might find any of these 3 ways more favorable than the others and choose to go with that :)
modelBuilder.RemovePluralizingTableNameConvention();
after base.OnModelCreating(builder)
otherwise the AspNetUser tables will get mangled. –
Kissee modelBuilder.RemovePluralizingTableNameConvention();
after base.OnModelCreating(modelBuilder);
does not solve problem when DbContext is inherited from IdentityDbContext
. ASP Identity table names are still mangled. –
Orthopter modelBuilder.RemovePluralizingTableNameConvention();
before base.OnModelCreating(builder);
and identity tables have OK names –
Bivouac modelBuilder.RemovePluralizingTableNameConvention()
causes issues when used in conjunction with entity.ToView("MyView")
: The entity is then tagged as a table and not as a view anymore. –
Marker EFCore.NamingConventions
. Because of this, I've decided to just use the TableAttribute
on all my entity classes and be totally explicit about what the name should be. Seems like the only way to get what I want (snake_case, singular). –
Aleuromancy entity.SetTableName(entity.DisplayName().ToSnakeCase());
–
Aleuromancy For EF Core 3.0 and above, use this to set the TableName
property (because entity.Relational()
no longer exist):
public static class ModelBuilderExtensions
{
public static void RemovePluralizingTableNameConvention(this ModelBuilder modelBuilder)
{
foreach (IMutableEntityType entity in modelBuilder.Model.GetEntityTypes())
{
if (entity.BaseType == null)
{
entity.SetTableName(entity.DisplayName());
}
}
}
}
...Only base type entity types can be mapped to a table.
. To work around this, I used the condition if (entity.BaseType == null)
. Base classes will return null
while inherited classes will obviously return the base type. –
Setaceous modelBuilder.RemovePluralizingTableNameConvention()
causes issues when used in conjunction with entity.ToView("MyView")
: The entity is then tagged as a table and not as a view anymore. –
Marker entity.SetTableName
exists in EF Core 6. –
Lemmueu The EF Core version doesn't seem to support entity.DisplayName
. This is a working alternative:
foreach (var entityType in modelBuilder.Model.GetEntityTypes())
{
// Skip shadow types
if (entityType.ClrType == null)
continue;
entityType.Relational().TableName = entityType.ClrType.Name;
}
entity.DisplayName
is an extension method in the Microsoft.EntityFrameworkCore.Metadata.Internal
namespace (which is actually public, not internal
). –
Clobber This is also an option:
using System.ComponentModel.DataAnnotations.Schema;
[Table("Book")]
public class Book
{...}
although you need to annotate it on each entity
The EF Core 5 has resolved using a switch "-NoPluralize" while updating the Db Context:
Scaffold-DbContext "..conn str.." Microsoft.EntityFrameworkCore.SqlServer -OutputDir EntityDbContext -Project DoctorsExpress.Domain -Force -NoPluralize
In Entity Framework NET core v2 you can choose to pluralize or singularize DbSets
and Collections
with a hook.
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;
}
}
See this answer for more information: https://mcmap.net/q/281550/-entityframework-core-database-first-approach-pluralizing-table-names
I use this for EF Core 3.1 to preserve [Table("some_table_name")]
annotation on entity types, although ConventionAnnotation
is an internal class.
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);
}
}
}
I went with adding a virtual
public virtual DbSet<TableName> TableName{ get; set; }
public DbSet<TableName> TableNames { get; set; }
TableNames.FirstOrDefault();
© 2022 - 2024 — McMap. All rights reserved.