.net core entity framework (EF Core) table naming convention plural to single/simple/underscore
Being a fan of single simple underscore
naming convention to table names, I feel uncomfortable with the way EF core is naming tables Plural PascalCase
.
Model
public class SourceType {
...
DbContext
public class ApplicationDbContext : DbContext {
public DbSet<SourceType> SourceTypes { get; set; }
...
This creates the table with the name SourceTypes
(PascalCase and Plural)
I know I can change the generated table name by using [table('source_type')]
in the model class.
But, what I need is a method to do it in global manner.
In short
Extend ModelBuilder with an extension method, do some regex, and call the method in you DbContext
In Detail
Create an extension for ModelBuilder
class
public static class ModelBuilderExtensions
{
public static void SetSimpleUnderscoreTableNameConvention(this ModelBuilder modelBuilder)
{
foreach (IMutableEntityType entity in modelBuilder.Model.GetEntityTypes())
{
Regex underscoreRegex = new Regex(@"((?<=.)[A-Z][a-zA-Z]*)|((?<=[a-zA-Z])\d+)");
entity.Relational().TableName = underscoreRegex.Replace(entity.DisplayName(), @"_$1$2").ToLower();
}
}
}
Call this method in you DbContext
public class ApplicationDbContext : DbContext
{
public DbSet<SourceType> SourceTypes { get; set; }
...
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
...
builder.SetSimpleUnderscoreTableNameConvention();
}
}
I hope this will help any developers like me not to waste time searching for the solution. :)
Faraj's answer not works on ThreeCapitalWords
, result is three_capitalwords
.
Here is my solution, based on this answer:
/// <summary>
///
/// </summary>
/// <param name="preserveAcronyms">If true, 'PrepareXXRecord' converted to 'prepare_xx_record',
/// otherwise to 'prepare_xxrecord'</param>
public static void SetSimpleUnderscoreTableNameConvention(this ModelBuilder modelBuilder, bool preserveAcronyms)
{
foreach (IMutableEntityType entity in modelBuilder.Model.GetEntityTypes())
{
var underscored = AddUndercoresToSentence(entity.DisplayName(), preserveAcronyms);
entity.Relational().TableName = underscored.ToLower();
}
}
private static string AddUndercoresToSentence(string text, bool preserveAcronyms)
{
if (string.IsNullOrWhiteSpace(text))
return string.Empty;
var newText = new StringBuilder(text.Length * 2);
newText.Append(text[0]);
for (int i = 1; i < text.Length; i++)
{
if (char.IsUpper(text[i]))
if ((text[i - 1] != '_' && !char.IsUpper(text[i - 1])) ||
(preserveAcronyms && char.IsUpper(text[i - 1]) &&
i < text.Length - 1 && !char.IsUpper(text[i + 1])))
newText.Append('_');
newText.Append(text[i]);
}
return newText.ToString();
}
It also converts acronyms: PrepareXXRecord
to prepare_xx_record
.