Singular Table Name Convention in Entity Framework Core v2

All development teams should have naming conventions in place for classes, variables, properties, database table names and foreign keys. One of the conventions we here at ClearlyAgile have used for many years is that database table names should be singular. Since a database table already implies a set of data, naming it in the plural form (i.e. Users vs. User) is redundant. If your team has different conventions, or none at all, you can stop reading here. But, if your team wants more control over Code First generated table names in Entity Framework Core 2 and make your friendly DBA happy, then please read on!

The previous incarnation of Entity Framework, version 6, allowed us to do some really cool things when generating a Code First data model. We have extensively used built-in and custom Code First Conventions in EF6 with most of our projects so that we could control how tables were named, how foreign keys were handled and how many-to-many relationships were constructed.

As we started to do some work with Entity Framework Core, we noticed right away that the Conventions we had made use of or removed (PluralizingTableNameConvention) in EF6 were no longer available. We had to come up with alternative ways to handle these conventions and make EF Core work for us. One of the first changes we wanted to make was to alter the default behavior of EF Core regarding the naming of database tables. By default, in EF Core 2.0, generated tables will use the same exact name as the DbSet property names in the DbContext. For example, if your DbContext looked like this:

public class MyAppDbContext : DbContext
{
   public MyAppDbContext(DbContextOptions options) : base(options)
   {
   }

   public DbSet<User> Users {get; set;}
   public DbSet<Company> Companies {get; set;}
}

and you were to add a migration for this context, EF Core 2 would generate the tables named Users and Companies respectively…not great for what we were looking for. Luckily for us, while Code First Conventions are gone, we can still insert some code into the OnModelCreating method of our MyAppContext to automatically singularize our table names:

public class MyAppDbContext : DbContext
{
   public MyAppDbContext(DbContextOptions options) : base(options)
   {
   }

   public DbSet<User> Users { get; set; }
   public DbSet<Company> Companies { get; set; }

   protected override void OnModelCreating(ModelBuilder modelBuilder)
   {
      //This will singularize all table names
      foreach (IMutableEntityType entityType in modelBuilder.Model.GetEntityTypes())
      {
         entityType.Relational().TableName = entityType.DisplayName();
      }
   }
}

Now, if we create a migration, EF Core 2 will generate tables named User and Company. Awesome!!!

Make sure that you reference the Microsoft.EntityFrameworkCore nuget package to gain access to the Relational() extension method used above.

Happy Coding!