Модель игнорирует свойство HasPrecision - PullRequest
0 голосов
/ 04 октября 2018

У меня есть приложение ASP.NET MVC5, которое используется для загрузки данных из файла CSV в таблицу базы данных SQL Server 2008 R2.

У меня есть модель,

public partial class SURCH
{
    [Key]
    [Column(Order = 0)]
    [StringLength(30)]
    [Display(Name = "Alloy")]
    public string ALLOY { get; set; }

    [Key]
    [Column(Order = 1, TypeName = "date")]
    [Display(Name = "Effetive Start Date")]
    [DataType(DataType.Date)]
    public DateTime EFFECTIVE_START_DATE { get; set; }

    [Key]
    [Column(Order = 2, TypeName = "date")]
    [Display(Name = "Efective End Date")]
    [DataType(DataType.Date)]
    public DateTime EFFECTIVE_END_DATE { get; set; }

    [Display(Name = "Cost")]
    public decimal COST { get; set; }
}

В моем классе DBContext я устанавливаю точность десятичного поля COST:

public partial class MyContext : DbContext
{
    public MyContext()
        : base("name=string")
    {
    }

    public virtual DbSet<SURCH> SURCH { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<SURCH>()
            .Property(e => e.COST)
            .HasPrecision(38, 4);
    }
}

Когда я импортирую свой CSV-файлЯ перебираю строки и создаю экземпляр этой модели для каждой строки.Поле COST в CSV может содержать до 4 десятичных знаков.Когда я создаю экземпляр модели, поле COST в модели имеет правильную точность.Однако, когда я добавляю модель в свою таблицу, поле COST всегда усекается до 2 десятичных знаков.

Вот как я добавляю свой список моделей в базу данных.

foreach (SURCH currentItem in SURCHlist)
{
    db.SURCH.Add(currentItem);
}

await db.SaveChangesAsync();

Почему мои данные усекаются?Я думал, что свойство HasPrecision справится с этим.

Я уже попробовал несколько вещей.Я попытался расширить класс DbConfiguration и указать, что он не должен усекать десятичные дроби.Я сохранил этот файл как DBContextConfiguration в той же папке, что и мой файл класса DBContext.

public class DbContextConfiguration : DbConfiguration
{
    public DbContextConfiguration()
    {
        var providerInstance = SqlProviderServices.Instance;
        SqlProviderServices.TruncateDecimalsToScale = false;
        this.SetProviderServices(SqlProviderServices.ProviderInvariantName, SqlProviderServices.Instance);
    }
}

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

EDIT1:

Пример входных данных из CSV:

1008M,1/1/1900,1/1/1900,0.119
100CRMO7,1/1/1900,1/1/1900,5.001

Пример выходных данных из базы данных:

1008M       1/1/1900    1/1/1900    0.12
100CRMO7    1/1/1900    1/1/1900    5.00

EDIT2: Моя таблица базы данных:

CREATE TABLE [dbo].[SURCH](
    [ALLOY] [nvarchar](30) NOT NULL,
    [EFFECTIVE_START_DATE] [date] NOT NULL,
    [EFFECTIVE_END_DATE] [date] NOT NULL,
    [COST] [decimal](38, 4) NOT NULL,
PRIMARY KEY CLUSTERED 
(
    [ALLOY] ASC,
    [EFFECTIVE_START_DATE] ASC,
    [EFFECTIVE_END_DATE] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

1 Ответ

0 голосов
/ 04 октября 2018

Я понял это после того, как понял, что есть две отдельные проблемы:

1) Моя модель не распознала свойство HasPrecision.После некоторого осмотра я нашел статью, в которой объяснялось, как создать собственную DataAnnotation для указания точности. В этой статье у автора была дополнительная строка в их функции OnModelCreating в классе DbContext.Я добавил эту строку в свою функцию, и вдруг все правильно сохранялось в базе данных.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // Added this line.
    base.OnModelCreating(modelBuilder);

    modelBuilder.Entity<SURCH>()
        .Property(e => e.COST)
        .HasPrecision(38, 4);
}

2) Мой вид не отображал правильный формат.Я предполагал, что, поскольку база данных и модель используют точность в 4 десятичных знака, мое представление автоматически сделает то же самое.Вместо этого он показывал по умолчанию 2 десятичных знака.Чтобы исправить это, я добавил DataAnnotation в свою модель, чтобы отформатировать поле COST в 4 десятичных знака, в том числе в режиме редактирования.

[Display(Name = "Cost")]
[DisplayFormat(DataFormatString = "{0:n4}", ApplyFormatInEditMode = true)]
public decimal COST { get; set; }
...