Skip to content

Instantly share code, notes, and snippets.

@hg
Last active May 1, 2026 18:36
Show Gist options
  • Select an option

  • Save hg/926015478292c9ebfef82ce94ff69534 to your computer and use it in GitHub Desktop.

Select an option

Save hg/926015478292c9ebfef82ce94ff69534 to your computer and use it in GitHub Desktop.
PostgreSQL / EF Core snake case naming

EFCore.NamingConventions is easier to use, but it does not rename "system" tables ("AspNetUsers" and the like).

protected override void OnModelCreating(ModelBuilder builder) {
  base.OnModelCreating(builder);

  // keep last or newly created objects won't be renamed
  RenameToSnakeCase(builder);
}

private static void RenameToSnakeCase(ModelBuilder builder) {
  var mapper = new NpgsqlSnakeCaseNameTranslator();

  foreach (var type in builder.Model.GetEntityTypes()) {
    var table = type.GetTableName();
    if (table != null) {
      type.SetTableName(mapper.TranslateMemberName(table));
    }

    var func = type.GetFunctionName();
    if (func != null) {
      type.SetFunctionName(mapper.TranslateMemberName(func));
    }

    var view = type.GetViewName();
    if (view != null) {
      type.SetViewName(mapper.TranslateMemberName(view));
    }

    foreach (var key in type.GetKeys()) {
      var name = key.GetName();
      if (name != null) {
        key.SetName(mapper.TranslateMemberName(name));
      }
    }

    foreach (var foreign in type.GetForeignKeys()) {
      var name = foreign.GetConstraintName();
      if (name != null) {
        foreign.SetConstraintName(mapper.TranslateMemberName(name));
      }
    }

    foreach (var index in type.GetIndexes()) {
      var name = index.GetDatabaseName();
      if (name != null) {
        index.SetDatabaseName(mapper.TranslateMemberName(name));
      }
    }

    foreach (var prop in type.GetProperties()) {
      prop.SetColumnName(mapper.TranslateMemberName(prop.GetColumnName()));
    }
  }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment