模型忽略HasPrecision属性

时间:2018-10-04 15:59:47

标签: c# sql-server-2008 entity-framework-6

我有一个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文件时,我会遍历行并为每一行创建此模型的实例。 CSV中的COST字段最多可以有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 :(得分:0)

我意识到存在两个独立的问题后才知道:

1)我的模型无法识别HasPrecision属性。环顾四周后,我发现了一篇文章,该文章解释了如何创建自己的DataAnnotation以指定精度。 In this article,作者在DbContext类的OnModelCreating函数中还有一行。我将此行添加到函数中,突然所有内容都正确保存到数据库中。

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