Is it possible to have a config setting to lower case table and column names?
adding double-quotes is more annoying than having a table name like aspnetusers.
Not really... that's not how EF6 really works.
You can still override names yourself with the fluent API (or with attributes) but the better way is have table and column names that exactly mirror your classes. If you're using EF6 in the first place you're not necessarily writing a lot of custom SQL (at least in theory), and if you are you need to bite the bullet and just add quotes...
I guess this was about the newer EF and not EF6?
yes this was about EF Core not EF 6
i was just thinking along the lines of how you can camel-case property names when you serialize an object to JSON ( CamelCasePropertyNamesContractResolver() ). Even though the Json object names do not match the C# property names exactly it sure does make it a lot easier when using the Json object in javascript.
Sorry, my bad, did not look at the repo the issue was in!
In my opinion it's a valid request, but which belongs in EF Core rather than in the Npgsql EF Core behavior. The idea of pluggable schemes for mapping c# names to database entiries could make sense in contexts beyond PostgreSQL/Npgsql...
I was think that it may belong in EF Core. but not knowing the inner workings of EF and how it is implemented i started here for a few reasons. Not all DBs are case sensitive and you probably don't want to lowercase names that are overridden in the fluent API or attributes, your overriding the name for a reason.
but i can see your point that this should be in EF Core. i will create a request in their repo.
https://github.com/aspnet/EntityFramework/issues/5159
thanks for the feedback
No problem @SepiaGroup. I think this could have value beyond PostgreSQL; a developer could simply decide they want to have snake-case tables (my_class_name) and have EF Core do the mapping automatically. This isn't necessarily related to lowercase.
Current code convert tables, properties, keys and indexes to snake case for Postgre, you can use it as a base for your custom conventions:
using System;
using System.Text.RegularExpressions;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Metadata;
using Npgsql;
namespace Database.Customization
{
public class PostgreDbContext : DbContext
{
private static readonly Regex _keysRegex = new Regex("^(PK|FK|IX)_", RegexOptions.Compiled);
public PostgreDbContext(DbContextOptions options)
: base(options)
{
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
FixSnakeCaseNames(modelBuilder);
}
private void FixSnakeCaseNames(ModelBuilder modelBuilder)
{
var mapper = new NpgsqlSnakeCaseNameTranslator();
foreach (var table in modelBuilder.Model.GetEntityTypes())
{
ConvertToSnake(mapper, table);
foreach (var property in table.GetProperties())
{
ConvertToSnake(mapper, property);
}
foreach (var primaryKey in table.GetKeys())
{
ConvertToSnake(mapper, primaryKey);
}
foreach (var foreignKey in table.GetForeignKeys())
{
ConvertToSnake(mapper, foreignKey);
}
foreach (var indexKey in table.GetIndexes())
{
ConvertToSnake(mapper, indexKey);
}
}
}
private void ConvertToSnake(INpgsqlNameTranslator mapper, object entity)
{
switch (entity)
{
case IMutableEntityType table:
var relationalTable = table.Relational();
relationalTable.TableName = ConvertGeneralToSnake(mapper, relationalTable.TableName);
if (relationalTable.TableName.StartsWith("asp_net_"))
{
relationalTable.TableName = relationalTable.TableName.Replace("asp_net_", string.Empty);
relationalTable.Schema = "identity";
}
break;
case IMutableProperty property:
property.Relational().ColumnName = ConvertGeneralToSnake(mapper, property.Relational().ColumnName);
break;
case IMutableKey primaryKey:
primaryKey.Relational().Name = ConvertKeyToSnake(mapper, primaryKey.Relational().Name);
break;
case IMutableForeignKey foreignKey:
foreignKey.Relational().Name = ConvertKeyToSnake(mapper, foreignKey.Relational().Name);
break;
case IMutableIndex indexKey:
indexKey.Relational().Name = ConvertKeyToSnake(mapper, indexKey.Relational().Name);
break;
default:
throw new NotImplementedException("Unexpected type was provided to snake case converter");
}
}
private string ConvertKeyToSnake(INpgsqlNameTranslator mapper, string keyName) =>
ConvertGeneralToSnake(mapper, _keysRegex.Replace(keyName, match => match.Value.ToLower()));
private string ConvertGeneralToSnake(INpgsqlNameTranslator mapper, string entityName) =>
mapper.TranslateMemberName(ModifyNameBeforeConvertion(mapper, entityName));
protected virtual string ModifyNameBeforeConvertion(INpgsqlNameTranslator mapper, string entityName) => entityName;
}
}
Updated for EfCore 3 => https://github.com/aspnet/EntityFrameworkCore/issues/5159#issuecomment-522223918
Please note also #933, which is about making a proper snake-case plugin.
Most helpful comment
Current code convert
tables,properties,keysandindexesto snake case forPostgre, you can use it as a base for your custom conventions: