-
Notifications
You must be signed in to change notification settings - Fork 226
Settings.PrependSchemaName
Puts the schema name in front of a generated class name, so two schemas can each have an Order table without colliding.
| Type | bool |
| Default | true |
| Applies to | EF 6 and EF Core |
| Databases | SQL Server, PostgreSQL and Oracle. MySQL has no schema within a database; SQLite is always main
|
In Database.tt? |
Yes |
dbo.Order and sales.Order cannot both generate a class called Order. So by default, any table outside
the default schema gets its schema prepended: sales.Order becomes sales_Order.
Two details people get wrong:
-
The schema is prepended exactly as the database spells it, not PascalCased. It is
sales_Order, notSales_Order. - The default schema is never prepended. Which schema counts as default is per-database - see Settings.DefaultSchema.
The fixture has dbo.Category, dbo.Product and sales.Order.
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>public interface IMyDbContext : IDisposable
public class MyDbContext : DbContext, IMyDbContext
public class MyDbContextFactory : IDesignTimeDbContextFactory<MyDbContext>
public class Category
public class Order
public class Product
public class CategoryConfiguration : IEntityTypeConfiguration<Category>
public class OrderConfiguration : IEntityTypeConfiguration<Order>
public class ProductConfiguration : IEntityTypeConfiguration<Product>sales_Order becomes Order. The table mapping is unchanged - the configuration still says
builder.ToTable("Order", "sales").
Leave it true unless you have looked and confirmed there are no clashes. It is a safety net, and it
fails loudly rather than silently: a clash you did not prevent becomes a compiler error.
Turn it off when every table name is unique across schemas, which is common when schemas are used for
organisation rather than for namespacing. sales_Order, sales_Invoice and sales_Customer are ugly for no
benefit if nothing in dbo shares those names.
Better: turn it off per schema.
Settings.PrependSchemaNameForTable keeps the safety net on everywhere
except the schemas you have checked:
Settings.PrependSchemaNameForTable = table =>
!table.Schema.DbName.Equals("sales", StringComparison.OrdinalIgnoreCase);That is almost always the right answer, and it is not in the shipped Database.tt, so most people never find
it.
Turning it off invites silent collisions. Two tables generating the same class name produce a compiler error pointing at generated code, which is a confusing place to start debugging.
It affects stored procedures too, and they have their own per-procedure override,
Settings.PrependSchemaNameForStoredProcedure.
On SQL Server, the default schema is SCHEMA_NAME(), not dbo. It is the connected login's default
schema. If yours is not dbo, then dbo is prepended and your dbo tables generate as dbo_Order. This
surprises people who connect as a non-standard user.
SQLite forces it off. The reader sets PrependSchemaName = false during initialisation because everything
is in main. Setting it in your .tt has no effect there.
Foreign key navigation properties honour the global setting but not the per-table callback. A relationship
crossing into a schema you exempted with PrependSchemaNameForTable can still use the prefixed name. Check the
generated navigation properties after exempting a schema other schemas point at.
- Settings.PrependSchemaNameForTable - the per-table version, which is usually what you want
- Settings.PrependSchemaNameForStoredProcedure
- Settings.DefaultSchema - which schema is exempt
- Settings.TableRename - full control over the name
- Settings Reference
- Settings A-Z - every setting, with a page each
- Common Settings Types Explained
- Settings Callbacks
- Settings runtime values and helpers
- Filtering
- Full Control Over the Generated Code
- Enum Generation from Table Data
- Owned Entities
- JSON column support
- Global Query Filters
- Extended Property Names Feature
- Partial Properties
- File-Scoped Namespaces
- Data Annotations
- Spatial Types
- HierarchyId
- RowVersion and TimeStamp columns
- Lazy Loading
- Stored proc result sets
- Custom File-Based Templates
- Extra entities via partial classes
- INotifyPropertyChanged
- Syntax colour for T4