Skip to content

Settings.StoredProcedureRename

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

Renames the generated method for a stored procedure, table-valued function or scalar function.

Type Func<StoredProcedure, string> - return the new name
Default Returns the name unchanged
Applies to EF 6 and EF Core
Databases All except SQLite, which has no stored procedures
In Database.tt? Yes, with a commented-out example

What it does

Database naming conventions and C# naming conventions rarely agree. sp_GetCustomerOrders is a perfectly normal procedure name and an embarrassing method name, and usp_, sp_, proc_ and my_sp_ prefixes are everywhere.

This callback runs once per procedure, after the name has been PascalCased and had any schema prefix applied, and whatever you return becomes the method name on the DbContext and its interface.

The StoredProcedure you are handed gives you NameHumanCase (the current name), DbName (the raw database name), Schema.DbName, and the IsStoredProcedure / IsTableValuedFunction / IsScalarValuedFunction flags so you can treat the three differently.

Example

Stripping a Get prefix:

Settings.StoredProcedureRename = delegate(StoredProcedure sp)
{
    return sp.NameHumanCase.StartsWith("Get")
        ? sp.NameHumanCase.Substring(3)
        : sp.NameHumanCase;
};

Before

List<GetStudentsByCourseReturnModel> GetStudentsByCourse(int? courseId);
List<sales_GetOrderTotalsReturnModel> sales_GetOrderTotals(int? year);

After

List<GetStudentsByCourseReturnModel> StudentsByCourse(int? courseId);
List<sales_GetOrderTotalsReturnModel> sales_GetOrderTotals(int? year);

The return model name follows the method, so GetStudentsByCourseReturnModel becomes StudentsByCourseReturnModel without any extra work.

When to use it

Stripping a house prefix, which is the reason this exists:

Settings.StoredProcedureRename = sp =>
{
    foreach (var prefix in new[] { "usp_", "sp_", "proc_" })
        if (sp.NameHumanCase.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
            return sp.NameHumanCase.Substring(prefix.Length);

    return sp.NameHumanCase;
};

Note that PascalCasing has already happened by this point, so match against sp.NameHumanCase as it now is - Usp rather than usp_ if the underscore has been consumed. Generate once and read the output before writing the rule.

Marking functions differently from procedures, so a call site can tell a cheap function from an expensive procedure:

if (sp.IsScalarValuedFunction)
    return sp.NameHumanCase + "Fn";

Resolving a clash with a table. A procedure called Customer and a table called Customer are fine in SQL and awkward in C#.

Gotchas

Renaming does not change what is executed. The generated method still calls [dbo].[sp_GetCustomerOrders]. Only the C# name moves.

Collisions are yours to avoid. Two procedures renamed to the same thing generate two methods with the same signature. Stripping prefixes is exactly the operation most likely to cause this - sp_GetOrders and usp_GetOrders both become GetOrders.

It runs for functions as well as procedures. A rule that assumes a procedure will rename your table-valued functions too. The three flags are there to prevent that.

It runs after the schema prefix is applied. A procedure in a non-default schema arrives as sales_GetOrderTotals, so a rule matching "GetOrderTotals" will not fire. Either match with Contains, or turn the prefix off for that schema with Settings.PrependSchemaNameForStoredProcedure.

Do not return an empty string. It generates a method with no name, which does not compile.

See also

Clone this wiki locally