S9118 — Default values should be compatible with their entity property type

Language
C#
Type
Bug
Severity
Major
Tags
entity-framework-core, entity-framework, database, orm

Passing a value of an incompatible type as a default value for an entity property or migration column can silently produce a broken schema, or fail inconsistently depending on the database provider, because Entity Framework Core’s default-value APIs accept the value as object? and give no compile-time type safety.

Why is this an issue?

Entity Framework Core’s default-value APIs — PropertyBuilder<T>.HasDefaultValue(), MigrationBuilder.AddColumn(), MigrationBuilder.AlterColumn(), and ColumnsBuilder.Column() — all type their defaultValue/value parameter as object?, never as the property’s or column’s actual .NET type, so the C# compiler cannot catch a mismatch: any value can be passed, whether or not it matches the target type.

Entity Framework Core’s own runtime handling of a type-incompatible default value is neither complete nor consistent:

That same loosely typed default value is round-tripped through Entity Framework Core’s type-mapping machinery twice: once when the schema or migration is generated, and again when the database’s default is materialized back into the property while reading a row. Passing a mismatched type is inherently fragile: whether it happens to work today depends on the current database provider and Entity Framework Core version, and it can silently stop working after either changes, or after a schema or migration is regenerated.

What is the potential impact?

A type mismatch that is not caught by Entity Framework Core can produce a database column whose default value does not match its declared type. For example, an int default value of 42 supplied for a string column can silently create the following schema, with no error raised anywhere in the process:


"Label" TEXT NOT NULL DEFAULT '42'

Whether a given mismatch fails at write time, fails at read time, or does not fail at all, is provider-dependent and cannot be reliably predicted from the code alone.

How to fix it

Make sure the value passed as a default matches the .NET type of the target property or column. When in doubt, verify the resulting schema explicitly, for example by inspecting a generated migration or reviewing context.Model, instead of relying on Entity Framework Core to flag an incompatibility.

Code examples

Noncompliant code example


public void Configure(EntityTypeBuilder<Student> builder)
{
    builder.Property(x => x.LastName) // LastName is a string property
        .HasDefaultValue(42); // Noncompliant: int passed as default value for a string property
}

Compliant solution


public void Configure(EntityTypeBuilder<Student> builder)
{
    builder.Property(x => x.LastName) // LastName is a string property
        .HasDefaultValue("42");
}

Resources

Documentation

Related rules

↑ Back to top