Git Product home page Git Product logo

Comments (9)

AuthorProxy avatar AuthorProxy commented on May 20, 2024 18

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

from efcore.pg.

roji avatar roji commented on May 20, 2024 16

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

from efcore.pg.

SepiaGroup avatar SepiaGroup commented on May 20, 2024 6

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.

from efcore.pg.

SepiaGroup avatar SepiaGroup commented on May 20, 2024 3

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.

dotnet/efcore#5159

thanks for the feedback

from efcore.pg.

Emill avatar Emill commented on May 20, 2024

I guess this was about the newer EF and not EF6?

from efcore.pg.

roji avatar roji commented on May 20, 2024

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

from efcore.pg.

roji avatar roji commented on May 20, 2024

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.

from efcore.pg.

williamdenton avatar williamdenton commented on May 20, 2024

Updated for EfCore 3 => dotnet/efcore#5159 (comment)

from efcore.pg.

roji avatar roji commented on May 20, 2024

Please note also #933, which is about making a proper snake-case plugin.

from efcore.pg.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.