3355307
3355307

Reputation: 1678

Correct way of implementing Singular Naming Convention and Data Annotations together in Entity Framework Core

I am using Entity Framework Core 2.2 and all database table names are singular so I am overriding pluralise naming convention in OnModelCreating method

 protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            foreach (IMutableEntityType entityType in modelBuilder.Model.GetEntityTypes())
            {
                entityType.Relational().TableName = entityType.DisplayName();
            }
        }

However in some cases entity names are different to table names for example

[Table("AzureSchemaVersionExecutionExtract", Schema = "dbo")]
    public class AzureDataExtract
    {
        public int Id { get; set; }
        public DateTime  DateApplied { get; set; }
    }

When i run the project it complains as it cannot find the table AzureDataExtract so i added following code in OnModelCreating method and it works. I need to know is this the correct way to implement Data Annotations and Singular Naming Convention together

protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            foreach (IMutableEntityType entityType in modelBuilder.Model.GetEntityTypes())
            {
                entityType.Relational().TableName = entityType.DisplayName();
            }
            modelBuilder.Entity<AzureDataExtract>().ToTable("AzureSchemaVersionExecutionExtract","dbo");
        }

Upvotes: 2

Views: 145

Answers (1)

Ivan Stoev
Ivan Stoev

Reputation: 205769

It's possible, but not with public API. But you already are using methods from Microsoft.EntityFrameworkCore.Metadata.Internal namespace, so that shouldn't be a problem - just check out if something is changed when upgrading to a newer EF Core version and update accordingly.

In EF Core 2.2 the trick is to use the internal Relational() method accepting ConfigurationSource and pass ConfigurationSource.Convention. Data annotations and regular fluent API have higher priority, so this will only override the internal EF Core table name convention which uses the DbSet name.

foreach (var entityType in modelBuilder.Model.GetEntityTypes().Where(t => !t.IsOwned())
{
    entityType.AsEntityType().Builder.Relational(ConfigurationSource.Convention)
        .ToTable(entityType.DisplayName());
}

Upvotes: 3

Related Questions