Framework
efcore/EFCore.NamingConventions avatar
efcore/EFCore.NamingConventions

EFCore.NamingConventions rewrites table and column names for EF Core

Entity Framework Core plugin to apply naming conventions to table and column names (e.g. snake_case)

961 stars95 forksC#Apache-2.0

At a glance

What is it?
This Entity Framework Core plugin renames tables, columns, and constraint names to snake_case or four other conventions at model configuration time. It is a small, focused library with one sharp edge: applying it to an existing database produces a renaming migration that drops and recreates primary keys.
Who is it for?
Adopt EFCore.NamingConventions when your database already uses a case or separator convention and you want the model, the migrations, and the generated SQL to agree on it from day one. Skip it if the schema is already live and populated, because the documented behaviour there involves a migration that renames everything and drops and recreates primary keys.
Can I use it commercially?
Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository last received commits 9 days ago.
What is it written in?
Mainly C#, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

EF Core names tables after your classes, which annoys database teams

Entity Framework Core maps tables and columns after the exact names of your .NET classes and properties. A Customer class with a FullName property becomes a Customers table with a FullName column. On PostgreSQL that is a practical problem, because unquoted identifiers are folded to lower case, so the framework has to wrap every identifier in double quotes. The README is blunt about the result: all those quotes are an eye sore. On SQL Server there is no quoting requirement, but the same friction appears for teams that simply do not want upper case letters in their schema. EFCore.NamingConventions is a plugin that resolves this at the configuration layer, so the naming rule lives in one place instead of being spelled out on every entity with a table attribute.

One extension method on OnConfiguring changes every identifier

The mechanism is deliberately small. The plugin adds extension methods that can be chained onto the DbContextOptionsBuilder inside the OnConfiguring method of your context. Enabling the snake case option means that every table and column in the model is mapped with that convention, without touching individual entity classes. The README states the same for the other conventions: lower case, camel case, upper case, and upper snake case, where FullName becomes fullname, fullName, FULLNAME, and FULL_NAME respectively. Because the change happens in the model configuration, it propagates to migrations and to the SQL EF Core generates at runtime. Nothing in the plugin depends on a specific database provider; the documentation states it works with any relational database provider and is not related to PostgreSQL or Npgsql in any way.

Turning on the convention in a DbContext

The README shows the entire activation path. You reference the EFCore.NamingConventions package, then chain the naming extension onto the options builder inside OnConfiguring, alongside your normal provider registration. The reader should see the provider call and the convention call in the same fluent chain:

csharp
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    => optionsBuilder
        .UseNpgsql(...)
        .UseSnakeCaseNamingConvention();

The package itself is published on NuGet under the name EFCore.NamingConventions, and the README links there for the reference step. The project offers no separate setup command or configuration file for this behaviour; the extension method is the entire configuration surface. If your application already centralises provider selection, adding one more chained call is the whole integration cost.

The generated SQL drops the double quotes on PostgreSQL

The before and after difference is easiest to read in SQL. Without the plugin, the framework emits a quoted, mixed case schema:

sql
CREATE TABLE "Customers" (
    "Id" integer NOT NULL GENERATED BY DEFAULT AS IDENTITY,
    "FullName" text NULL,
    CONSTRAINT "PK_Customers" PRIMARY KEY ("Id")
);

With the snake case convention enabled, the same model produces lowercase identifiers with underscores and no quoting on the table or column names:

sql
CREATE TABLE customers (
    id integer NOT NULL GENERATED BY DEFAULT AS IDENTITY,
    full_name text NULL,
    CONSTRAINT "pk_customers" PRIMARY KEY (id)
);

The constraint name in the second listing still carries double quotes in the README example, which tells you the plugin is rewriting the names of the objects it maps rather than rewriting how the provider quotes everything. The select statement follows the same pattern, moving from c."Id", c."FullName" to c.id, c.full_name. For a team that has been fighting generated SQL full of quoted PascalCase identifiers, that difference is the entire point of the library.

Applying it to an existing database produces a renaming migration

This is the limitation worth reading twice. The documentation states that if you have an existing database, adding the naming convention will cause a migration to be produced that renames everything, and advises being very cautious because the process currently involves dropping and recreating primary keys. A rename migration is not a cheap operation on a live table with data and foreign keys pointing at it. The practical reading is that this plugin belongs at the start of a project's life, not in a release that changes an established schema. If your schema already exists and is populated, the cost of the convention is likely to exceed what it buys you, and you would need to plan the primary key rebuild deliberately rather than let it appear inside an ordinary migration.

Community maintained, version matched to EF Core releases

The README states plainly that this is a community maintained plugin: it is not an official part of Entity Framework Core and is not supported by Microsoft in any way. That framing matters for adoption decisions, because it means the package carries no compatibility guarantee from the EF Core team. The project is licensed under Apache-2.0, which allows commercial use and modification, with the notice and licence terms retained in redistribution. The repository carries a solution file, a test project named EFCore.NamingConventions.Test, a Directory.Build.props, a Directory.Packages.props, a global.json, and a strong name key file, so central package version management and a signed assembly are part of the build. The last push to the repository was on 2026-10-14, and the recent releases are version matched to the framework, with 10.0.0 and 10.0.1 both published on 2026-01-22 after a 10.0.0-rc.1 release in 2025-09.

The alternative is naming everything by hand

The obvious alternative is to configure names explicitly on each entity and property using the table and column attributes or the fluent API. That approach has a real advantage: it works on every EF Core version, needs no package, and makes each name visible right where the entity is defined. Its cost is repetition. A project with two hundred entities needs two hundred decisions and two hundred places to edit when a naming rule changes, and the schema names then drift from whatever the application code would have produced. The plugin takes the opposite trade, deciding names globally from the options builder so that the model, the migrations, and the database agree by construction. Where the two approaches meet is the constraint naming seen in the SQL examples: the plugin controls table and column names, and a project that also wants its own index or foreign key naming still has to handle that separately.

Adding a new convention means writing a small provider

The README invites readers who want another convention to open an issue or submit a pull request, and states that it is pretty easy to do. That invitation is a signal about the design: a convention is an isolated piece of name transformation, so extending the set does not require touching the model pipeline. For teams whose organisation has its own house style, for example a kebab case or a prefixed schema naming scheme, this extension point matters more than the five built in options do. The documentation does not describe the interface a custom convention implements, so anyone planning to write one will need to read the source rather than the README alone.

Editorial conclusion

Adopt EFCore.NamingConventions when your database already uses a case or separator convention and you want the model, the migrations, and the generated SQL to agree on it from day one. Skip it if the schema is already live and populated, because the documented behaviour there involves a migration that renames everything and drops and recreates primary keys. Before you enable it on a fresh project, confirm that your provider accepts unquoted identifiers in the target convention, and check the plugin version you pin against the Entity Framework Core major version in your application, since the project ships version matched releases such as 10.0.0 and 10.0.1.

Frequently asked questions

How do I add EFCore.NamingConventions to an EF Core project?

Reference the EFCore.NamingConventions package from NuGet, then chain UseSnakeCaseNamingConvention onto the options builder in the OnConfiguring method of your DbContext.

Which naming conventions does EFCore.NamingConventions support?

The README lists snake case, lower case, camel case, upper case, and upper snake case. For example, the FullName property becomes full_name, fullname, fullName, FULLNAME, or FULL_NAME depending on the option you choose.

Does EFCore.NamingConventions only work with PostgreSQL?

No. The documentation states that the plugin works with any relational database provider and is not related to PostgreSQL or Npgsql in any way, even though the README examples use PostgreSQL.

What happens if I add a naming convention to a database that already exists?

The documentation states that a migration will be produced that renames everything, and advises caution because the process currently involves dropping and recreating primary keys.

Official sources

  1. efcore/EFCore.NamingConventions on GitHub
  2. Issues
  3. License: Apache-2.0
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/efcore-efcore-namingconventions.svg)](https://hysenlabs.com/projects/efcore-efcore-namingconventions)

Was this useful?