.net core entity framework (EF Core) table naming convention

c# entity-framework entity-framework-core

Question

.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.

1
3
9/19/2016 5:58:15 PM

Accepted Answer

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. :)

2
9/16/2016 10:00:48 PM

Popular Answer

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.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow