Skip to content

Settings.IncludeColumnsWithDefaults

Simon Hughes edited this page Sep 29, 2026 · 3 revisions

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

What it does

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.

Example

Product.UnitPrice is declared decimal(18, 2) NOT NULL CONSTRAINT DF_Product_UnitPrice DEFAULT ((0)).

Settings.IncludeColumnsWithDefaults = true (default)

    // 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;
        }
    }

Settings.IncludeColumnsWithDefaults = false

    // 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.

When to use it

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.

Gotchas

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.

See also

Clone this wiki locally