Skip to content

Settings.TableRename

Simon Hughes edited this page Sep 10, 2026 · 2 revisions

Renames a table before anything else happens to it, so every later step sees your name instead of the database's.

Type Func<string, string, bool, string> - parameters (name, schema, isView), returns the new name
Default Returns the name unchanged
Applies to EF 6 and EF Core
Databases All
In Database.tt? Yes, with commented-out examples

What it does

This is the first thing that happens to a table name, and that is what makes it different from the other renaming hooks. Whatever you return here is what gets singularised, PascalCased, schema-prefixed, checked for clashes, and turned into a class name, a DbSet name and a set of navigation property names.

So it is the right place for wholesale surgery - stripping a prefix every table in the database carries - and the wrong place for one-off tweaks, which are easier in Settings.UpdateTable where you can see the finished name.

Settings.TableRename = delegate(string name, string schema, bool isView)
{
    // Strip a 'tbl' prefix the whole database uses
    if (name.StartsWith("tbl"))
        name = name.Remove(0, 3);

    // Mark views so they read differently at the call site
    if (isView)
        name = name + "View";

    return name;
};

Example

Renaming Product to CatalogueItem:

Settings.TableRename = (name, schema, isView) => name == "Product" ? "CatalogueItem" : name;

Before

public interface IMyDbContext : IDisposable
public class MyDbContext : DbContext, IMyDbContext
public class MyDbContextFactory : IDesignTimeDbContextFactory<MyDbContext>
public class Category
public class Product
public class sales_Order
public class CategoryConfiguration : IEntityTypeConfiguration<Category>
public class ProductConfiguration : IEntityTypeConfiguration<Product>
public class sales_OrderConfiguration : IEntityTypeConfiguration<sales_Order>

After

public interface IMyDbContext : IDisposable
public class MyDbContext : DbContext, IMyDbContext
public class MyDbContextFactory : IDesignTimeDbContextFactory<MyDbContext>
public class CatalogueItem
public class Category
public class sales_Order
public class CatalogueItemConfiguration : IEntityTypeConfiguration<CatalogueItem>
public class CategoryConfiguration : IEntityTypeConfiguration<Category>
public class sales_OrderConfiguration : IEntityTypeConfiguration<sales_Order>

The class, the configuration class and the DbSet all follow, and so does the navigation property on Category, which becomes ICollection<CatalogueItem> CatalogueItems. That is the whole point of renaming this early: you rename once and everything downstream agrees.

When to use it

  • A prefix or suffix the entire database carries. tbl_, T_, a system code, a country suffix.
  • Names that are not legal C# identifiers, or that collide with a keyword.
  • Views you want to distinguish from tables at the call site.
  • A table whose database name is simply wrong and cannot be changed.

Gotchas

Rename to the plural if you use pluralisation. The generator singularises whatever you return in order to name the class, then pluralises it again for the DbSet. If you have registered a custom pluralisation entry such as new CustomPluralizationEntry("Tree", "Trees"), return "Trees", not "Tree" - returning the singular defeats the entry you just added.

Filters run against the database name, not this one. FilterSettings.TableFilters has already been applied by the time a table gets here, so renaming cannot rescue a table you filtered out, and a filter cannot match a name that only exists because of this callback. See Filtering.

Watch for collisions. Two tables renamed to the same thing generate two classes with the same name. The generator does not check; the compiler does.

schema is the raw database schema name, so compare it case-insensitively - dbo and DBO are the same schema on SQL Server but not the same string.

It runs for views as well as tables, which is what isView is for. A rule that assumes tables will quietly rename your views too.

See also

Clone this wiki locally