Wie man Entity Framework Core dazu bringt, die Klassennamen statt der DbSet-Namen als Tabellennamen zu verwenden

Der Dotnet-Doktor  –  3 Kommentare

Microsofts objektrelationaler Mapper Entity Framework Core hat eine aus meiner Sicht unangenehme Grundeinstellung: Die Datenbanktabellen heißen nicht wie die Klassennamen der Entitätsklassen, sondern wie die Property-Namen, die in der Kontextklasse bei der Deklaration des DbSet<T> verwendet werden.

Also eine Klasse "Schulung" für die es in der Kontextklasse die Deklaration

public class WWWingsContext : DbContext
{
public DbSet<Schulung> SchulungSet { get; set; }
...
}

gibt, bekommt dann nicht den Tabellennamen "Schulung", sondern "SchulungSet". Nun könnte ich den Tabellennamen einzeln für jede Entitätsklasse festlegen, in dem ich die Datenannotation [Table("Schulung")] vor class Schulung verwende, oder aber im Fluent-API festlege:

protected override void OnModelCreating(ModelBuilder mb)
{
mb.Entity<Flight>().ToTable("Flight");
...
}

Das macht mir bei größeren Anwendungen keinen Spaß.

Die Lösung ist folgende Massenkonfiguration, die den Tabellennamen für alle Entitätsklassen in einer Kontextinstanz auf den Klassennamen festgelegt, sofern nicht Table[("Name")] zum Einsatz kommt und insofern die Klasse nicht abgeleitet ist von einer anderen (wo EF Core 3.0 keinen Table()-Aufruf mehr erlaubt):

protected override void OnModelCreating(ModelBuilder mb)
{
#region Bulk configuration via model class for all table names
foreach (IMutableEntityType entity in mb.Model.GetEntityTypes())
{
// All table names = class names (~ EF 6.x),
// except the classes that have a [Table] annotation or derived classes (where ToTable() is not allowed in EF Core >= 3.0)
var annotation = entity.ClrType?.GetCustomAttribute<TableAttribute>();
if (annotation == null && entity.BaseType == null)
{
entity.Relational().TableName = entity.DisplayName();
}
}
#endregion
...
}