anon
anon

Reputation:

Database column defaults not behaving as expected

I have an issue where writing a new entry to the database isn't using the configured default values as I'd expect.

I have some classes:

public class Benefits
{
    public string Id { get; set; }

    [Required, ForeignKey("Id"), JsonIgnore]
    public Employee Employee { get; set; }

    [Column(TypeName = "money")]
    public decimal BenefitsCost { get; set; }

    [Column(TypeName = "decimal(16,8)"), DefaultValue(1)]
    public decimal Modifier { get; set; }

}

public class BenefitsEmployee : Benefits
{}

public class BenefitsDependent : Benefits
{
    [Required]
    public string NameFirst { get; set; }

    [Required]
    public string NameLast { get; set; }
}

In OnModelCreating:

builder.Entity<BenefitsEmployee>().Property(b => b.BenefitsCost).HasDefaultValue(1000);
builder.Entity<BenefitsDependent>().Property(b => b.BenefitsCost).HasDefaultValue(500);

And, as last step in Configure, roughly:


var user = new {
    Id = "SomeId",
    NameFirst = "FirstName",
    NameLast = "LastName",
    SalaryBase = 0,
    BenefitsCost = 0,
};

var emp = new Employee
{
    Id = user.Id,
    NameFirst = user.NameFirst,
    NameLast = user.NameLast,
    SalaryBase = user.SalaryBase,
    BenefitsEmployee = new BenefitsEmployee
    {
        BenefitsCost = user.BenefitsCost,
    },
};

await context.AddAsync(emp);

await context.SaveChangesAsync();

The problem is that BenefitsCost is set to 1000 and Modifier is set to 0 rather than 0 and 1 as I'd expect.

What might I be doing wrong?

Upvotes: 0

Views: 340

Answers (1)

atiyar
atiyar

Reputation: 8338

You are setting 0 to BenefitsCost, which is the default value for decimal type. EF will not even include that column in the generated SQL. That's because from EF's perspective, setting 0 to BenefitsCost is equivalent to not setting any value at all, and what it sees is - the user didn't set a value and this column has a default value defined. Therefore, it doesn't bother to include the column in the generated SQL. And for the absent column, the configured default value is supposed to get inserted.

As a solution you can make BenefitsCost a nullable type (decimal?). That way, if you set the value 0, EF will know that you have set a value explicitly. Also, in your configuration, you have to mark the default values as decimal, like 1000m, 500m etc.

For the Modifier, configure the default value in OnModelCreating like others. In my experience, setting default value with [DefaultValue()] attribute doesn't work. You wouldn't even find the mention of default value in the migration script. May be its a bug, but I'm not sure.

Upvotes: 2

Related Questions