Как добавить decimal в базу данных Access через EF Core?

111
10 апреля 2021, 02:00

Имем сущность Contracts со свойством Salary. Добавление в базу с помощью метода Add(). Изначально Salary был типом float, модель и сущности были сгенерированы провайдером Jet (он используется для Access).

Разбирая другие свои вопросы, мне несколько раз указывали на то, что Salary, то есть Зарплату необходимо держать в decimal. Я исправил тип и все связанные с этим участки кода (это переводы из текста и обратно, когда значение уходит в контрол и из него).

Поле Salary в базе данных исправлял на (в самом Access через GUI) Денежный, Одинарное с плавающей точной, Двойное с плавающей точной, Действительные. Если Salary в коде будет decimal без дробной части, добавление пройдет успешно. Когда там будет дробная часть, падает исключение:

Data type mismatch in criteria expression

Когда Salary в коде float или double, добавление корректно и с дробной частью, и без.

Перевод из текста пробовал и через decimal.Parse(), и через Convert.ToDecimal()

Отсюда вопрос, как добавить decimal в Access? К слову, вся математика над данным полем описывается свойством SalaryWithTax

public partial class Contracts
{
    ...
    //public double Salary { get; set; }
    //public float Salary { get; set; }
    public decimal Salary { get; set; }
    ...
}
static public bool Add(object obj)
{
    bool result = true;
    try
    {
        using (ModelContext context = new ModelContext())
        {
            context.Add(obj);
            context.SaveChanges();
        }
    }
    catch (Exception ex) { ... }
    return result;
}
// в данный момент все указанные переменные в double
public double SalaryWithTax
{
    get { return salaryWithTax; }
    set
    {
        salaryWithTax = value;
        incomeTaxValue = (salaryWithTax * incomeTaxProcent) / 100;
        insuranceTaxValue = (salaryWithTax * insuranceTaxProcent) / 100;
        Salary = salaryWithTax - incomeTaxValue - insuranceTaxValue;
    }
}

Update

Поставил тип Действительное для Salary в базе данных и пересоздал модель через провайдера Jet. Salary сущности Contracts получило тип decimal. В OnModelCreating() добавилось .HasColumnType("decimal(18, 2)"). Но по прежнему тоже исключение при добавлении числа с дробью. По дебагу видно, что Parse() или Convert() делают нормальное число. Access 2016, база .accdb

Update 2

Я создал новую базу данных Access с таблицей Table (int id иdecimal salary). Модель создана провайдером Jet:

Scaffold-DbContext -Connection "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=nameDB.accdb;" -Provider EntityFrameworkCore.Jet

И консольную программу с таким Main():

using(ModelContext context = new ModelContext())
{
    decimal x = 17.45M;
    Table table = new Table();
    table.Id = 1;
    table.Salary = x;
    context.Table.Add(table);
    context.SaveChanges(); // исключение падает тут
}

Получаю тоже самое исключение. Приведу полный текст:

Microsoft.EntityFrameworkCore.DbUpdateException: "An error occurred while updating the entries. See the inner exception for details."

OleDbException: Data type mismatch in criteria expression.

Код OnConfiguring() создался такой. Я пробовал менять строку .HasColumnType("decimal(18, 0)") на 18, 2 (в базе тоже) - никак не влияет, тоже самое исключение.

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.HasAnnotation("ProductVersion", "2.2.6-servicing-10079");
    modelBuilder.Entity<Table>(entity =>
    {
        entity.ToTable("table");
        entity.Property(e => e.Id).HasColumnName("id");
        entity.Property(e => e.Salary)
            .HasColumnName("salary")
            .HasColumnType("decimal(18, 0)")
            .HasDefaultValueSql("0");
    });
}

Ссылка на скачивание консольной программы.

READ ALSO
Пропадает заголовок запроса

Пропадает заголовок запроса

Отправляю запрос с заголовком AutorizationЕсли смотреть данные о запросе через кастомный middleware, то он там есть

118
Механизм работы виртуальных методов в C#

Механизм работы виртуальных методов в C#

Мне немного не ясен механизм работы виртуальных методов в C#Знаю, что для каждого класса, имеющего виртуальные методы, есть своя таблица виртуальных...

89
Объясните смысл конструкции [In, Out] byte[] array

Объясните смысл конструкции [In, Out] byte[] array

встретил такую конструкцию в кодяре: [In, Out] byte[] array Передается как параметрДайте пожалуйста четкое конкретно объяснение, зачем оно нужно,...

100
WPF Объединение ContextMenu разных контролов

WPF Объединение ContextMenu разных контролов

Есть два любых контролаОдин главный, второй дочерний

81