简体   繁体   中英

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");
        }

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());
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM