Столбцы базы данных по умолчанию ведут себя не так, как ожидалось

#entity-framework-core #asp.net-core-5.0

#entity-framework-core #asp.net-core-5.0

Вопрос:

У меня проблема, когда при записи новой записи в базу данных не используются настроенные значения по умолчанию, как я ожидал.

У меня есть несколько классов:

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

В OnModelCreating :

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

И, как последний шаг Configure , примерно:

 
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();

 

Проблема в том, что BenefitsCost для него установлено значение 1000 и Modifier установлено 0 значение, а не 0 и 1 , как я и ожидал.

Что я могу делать неправильно?

Ответ №1:

Вы устанавливаете 0 значение BenefitsCost , которое является значением по умолчанию для decimal type . EF даже не включит этот столбец в сгенерированный SQL. Это потому, что с точки зрения EF установка 0 значения BenefitsCost эквивалентна отсутствию какого-либо значения вообще, и то, что он видит, — пользователь не установил значение, и в этом столбце определено значение по умолчанию. Поэтому нет необходимости включать столбец в сгенерированный SQL. И для отсутствующего столбца должно быть вставлено настроенное значение по умолчанию.

В качестве решения вы можете создать BenefitsCost тип с нулевым значением (десятичный?). Таким образом, если вы зададите значение 0 , EF будет знать, что вы задали значение явно. Кроме того, в вашей конфигурации вы должны пометить значения по умолчанию как decimal 1000m , 500m например, и т.д.

Для Modifier , настройте значение по умолчанию в OnModelCreating , как и другие. По моему опыту, установка значения по умолчанию с [DefaultValue()] помощью атрибута не работает. Вы даже не найдете упоминания значения по умолчанию в сценарии миграции. Может быть, это ошибка, но я не уверен.

Комментарии:

1. Что касается BenefitCost , есть ли какой-нибудь способ обойти эту «особенность»? Помимо использования 0 по умолчанию?

2. @Ouroborus Я предоставил информацию исключительно на основе моего наблюдения за сгенерированным SQL. Все еще может быть какое-то обходное решение или даже допустимая конфигурация, о которой я не знаю. Вы можете использовать 0.1 вместо 0 . Я постараюсь обновить ответ и уведомить вас, если смогу найти какую-либо полезную информацию.

3. @Ouroborus Я обновил сообщение, чтобы добавить решение. Короче говоря, измените BenefitsCost на decimal? type .

4. Я думаю, что случайно наткнулся на это и не осознал этого. Сейчас я использую decimal? и устанавливаю предполагаемые значения по умолчанию в конструкторах, используя инициализаторы объектов и условные назначения для обновления значений по мере необходимости.