-
Notifications
You must be signed in to change notification settings - Fork 226
Settings.IncludeColumnsWithDefaults
Copies each column's database default into the generated C# property, so a new entity starts out matching what the database would have produced.
| Type | bool |
| Default | true |
| Applies to | EF 6 and EF Core |
| Databases | All |
In Database.tt? |
Yes |
A column declared DEFAULT ((0)) gets that value when you INSERT without naming it. But new Product() in
C# gives you UnitPrice = 0 only because decimal happens to default to zero - and for
DEFAULT (getutcdate()) or DEFAULT ('Pending') you would get nothing useful at all.
With this on, the generator reads the default out of the schema and initialises the property with it, so an entity you construct in memory looks like a row the database would have created.
Where the value lands depends on
Settings.UsePropertyInitialisers: a generated constructor by default, or
a property initialiser if you turn that on.
Product.UnitPrice is declared decimal(18, 2) NOT NULL CONSTRAINT DF_Product_UnitPrice DEFAULT ((0)).
// Product
public class Product
{
public int ProductId { get; set; } // ProductId (Primary key)
public string ProductName { get; set; } // ProductName (length: 100)
public decimal UnitPrice { get; set; } // UnitPrice
public string Notes { get; set; } // Notes
public int CategoryId { get; set; } // CategoryId
public string DisplayLabel { get; private set; } // DisplayLabel (length: 150)
// Foreign keys
/// <summary>
/// Parent Category pointed by [Product].([CategoryId]) (FK_Product_Category)
/// </summary>
public Category Category { get; set; } // FK_Product_Category
public Product()
{
UnitPrice = 0m;
}
} // Product
public class Product
{
public int ProductId { get; set; } // ProductId (Primary key)
public string ProductName { get; set; } // ProductName (length: 100)
public decimal UnitPrice { get; set; } // UnitPrice
public string Notes { get; set; } // Notes
public int CategoryId { get; set; } // CategoryId
public string DisplayLabel { get; private set; } // DisplayLabel (length: 150)
// Foreign keys
/// <summary>
/// Parent Category pointed by [Product].([CategoryId]) (FK_Product_Category)
/// </summary>
public Category Category { get; set; } // FK_Product_Category
public Product()
{
}
}With it off, the constructor disappears - there is nothing left for it to do.
Leave it true. It makes an in-memory entity behave like a database row, which is what people expect and
what makes unit tests against a FakeDbContext agree with integration tests against the real thing.
Turn it off when the default is the database's job and yours should stay unset. The common case is an
audit column defaulted to getutcdate(): with this on, the generator writes today's semantics into your code,
and the value it sets is the time the entity was constructed rather than the time it was inserted. If you
want the database to own that, suppress it here and let EF omit the column.
The default is frozen at generation time. The generator reads it once and writes it into your code. Change the default in the database and nothing tells you the two have diverged - you have to re-run the generator.
Only literals and a few functions reach the POCO. A literal like ((0)), ('Pending') or PostgreSQL's
'{1,2}' array maps cleanly. A handful of functions have a C# equivalent and use it - newid() becomes
Guid.NewGuid(), and getdate() or sysutcdatetime() become DateTime.Now or DateTime.UtcNow when they
are the whole default. Any other default is SQL the generator cannot run in C# - SUSER_SNAME(),
CURRENT_USER, now(), DATEADD(DAY, 30, GETDATE()) - so the property gets no initial value, and on EF Core
the column gets .HasDefaultValueSql() instead, which leaves it to the database. Read the generated code rather
than assuming.
EF 6 has no HasDefaultValueSql, so for an expression default it can only send what the property holds.
Set those properties yourself, or the insert carries a null or DateTime.MinValue. The exception is a date
default containing the current time, such as DATEADD(DAY, 30, GETDATE()): on EF 6 that still becomes
DateTime.Now, an approximation, because that is better than DateTime.MinValue.
MySQL needs efrpg 1.2.0 or later to be exact. MySQL reports the literal 'uuid()' and the expression
(UUID()) as the same text, and only the tool can ask the catalogue which one it is. With an older tool the
generator guesses from the text: a function call or a date keyword is taken as an expression.
A defaulted column is still sent on insert. Initialising the property means EF sees a value and writes it,
so the database default never fires. That is usually harmless - the values agree - but it means a change to
the database default has no effect on rows your application inserts. Expression defaults are the exception:
with no value in the POCO and .HasDefaultValueSql() in the model, EF Core leaves the column out.
This is not HasDefaultValueSql.
Settings.GenerateHasDefaultValueSql puts the default into the EF
model, where it is queryable by reflection and used by migrations. This setting puts it into the POCO. They
are independent, and it is reasonable to want both or neither.
Computed columns are not defaults and are unaffected. They have their own handling - see
Settings.UsePrivateSetterForComputedColumns.
- Settings.UsePropertyInitialisers - constructor or property initialiser
- Settings.GenerateHasDefaultValueSql - the default in the EF model instead
- Settings.UsePrivateSetterForComputedColumns - the related but different case
- Settings Reference
- Home
- Compared with the Microsoft scaffolder
- Connection strings
- JetBrains Rider
- Upgrading from v3 to v4
- Saving .tt does nothing
- 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