实体框架代码首先截断我的小数 [英] Entity Framework Code First truncating my decimals

查看:31
本文介绍了实体框架代码首先截断我的小数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在 MVC 5 应用程序上使用 Code First 方法使用 Entity Framework 6.x.在这种特殊情况下,我的模型(除其他外)包含两个名为纬度和经度的属性:

[必填,范围(-90, +90)]公共十进制纬度{获取;放;}[必需,范围(-180,+180)]公共十进制经度{得到;放;}

当我执行迁移时,我得到了类似的东西

CreateTable("ResProperty"), c =>新的 {:纬度 = c.Decimal(可为空:false,精度:10,比例:8),经度= c.Decimal(可为空:false,精度:11,比例:8),:})... 其他的东西

所以纬度和经度都有 8 个十进制位.前者有 2 个整数(最多 90),后者有 3 个整数(最多 180).

执行 Update-Database 命令后,我的表的列显示为:

纬度小数(10,8)经度小数(11,8)

这对我来说似乎很好.现在在我看来,我有一个地图和 Javascript 代码,允许用户重新定位标记.这也很好.当标记重新定位时,纬度和经度字段将填充更新的值,该值 (Javascript) 具有超过 12 个十进制数字.AFAIK 没关系,因为我的比例是小数点后 8 位.

在按下提交按钮并调用 Create 或 Edit POST 方法后,我检查模型实例并确认模型中传递给控制器​​的实际值是正确的,它们有足够多的十进制数字(那些那个Javascript代码的地方).所以这个值是正确的.

现在......问题是在执行 db.SaveChanges() 后数据库得到更新 - 我已经确认已经发生了实际的写入/更新 - 但不知何故,EF 在内部忽略了我的实际值并写入截断纬度/经度四舍五入到只有两位十进制数字,所以我的纬度在数据库中显示为 09.500000000 所有其他十进制数字都归零,因为似乎已经发生了四舍五入.

//在 SaveChanges() 之前纬度 = 9.08521879经度 = -79.51658792//在 SaveChanges() 之后纬度 = 9.08000000经度 = -79.51000000

如果我给出了正确的比例和精度,并且列也有正确的比例和精度,为什么还要舍入它?为什么 SaveChanges 会改变我的价值观?

我找到了这篇文章(http://weiding331.blogspot.com/2014/01/entity-framework-decimal-value.html) 这是同样的问题,但我不知道如何解决这个问题(如果有的话),因为我已经执行了几次迁移并且在有问题的表被迁移"之后添加的数据.

总结

  • 模型数据类型正确(十进制)
  • 数据库迁移代码具有正确的精度/比例(lat 10/8 lon 11/8)
  • SQL 数据库列具有正确的精度/比例(lat 10/8,long 11/8)
  • 模型中传递的经纬度值至少有 8 位小数
  • 值的实际写入/更新发生在数据库中,没有错误,但是...
  • 数据库中记录的这两列的值被截断为两位十进制数字,并且将其他最低有效十进制数字显示为零 (0)

解决方案

EF 对 SqlProviderServices 有一个特殊的属性(SQL Server 的 SqlClient 提供程序的实现) - TruncateDecimalsToScale.默认值为 true,因此您可以将其更改为 false 值.例如:

公共类 DbContextConfiguration : DbConfiguration{公共 DbContextConfiguration(){var now = SqlProviderServices.Instance;SqlProviderServices.TruncateDecimalsToScale = false;this.SetProviderServices(SqlProviderServices.ProviderInvariantName, SqlProviderServices.Instance);}}[DbConfigurationType(typeof(DbContextConfiguration))]公共类 MyContext : DbContext{ ... }

更多信息:https://msdn.microsoft.com/en-us/library/system.data.entity.sqlserver.sqlproviderservices.truncatedecimalstoscale%28v=vs.113%29.aspxp>

I am using Entity Framework 6.x using the Code First approach on an MVC 5 application. In this particular situation my model (among other things) contains two properties named Latitude and Longitude:

[Required, Range(-90, +90)]
public decimal Latitude { get; set; }

[Required, Range(-180, +180)]
public decimal Longitude { get; set; }

And when I performed the migration I got something like this

CreateTable("ResProperty"), c => new {
        :
    Latitude = c.Decimal(nullable: false, precision: 10, scale: 8),
    Longitude = c.Decimal(nullable: false, precision: 11, scale: 8),
        :
})
... other stuff

so both latitude and longitude have 8 decimal digits. The former with 2 whole numbers (max 90) and the latter with 3 whole numbers (max 180).

After performing the Update-Database command my table's columns are shown as:

Latitude decimal(10,8)
Longitude decimal(11,8)

that seems good to me. Now In my view I have a map and Javascript code that allows the user to reposition the marker. That works fine too. When the marker is repositioned the Latitude and Longitude fields are populated with the updated value which (Javascript) has more than 12 decimal digits. That does not matter AFAIK because my scale is 8 decimals.

After the submit button is pressed and either the Create or Edit POST method is invoked I examine the model instance and I confirmed that the actual values passed in the model to the controller are correct, they have more than enough decimal digits (those that Javascript code place). So the value is correct.

Now... the problem being that after db.SaveChanges() is performed the database gets updated -and I have confirmed that an actual write/update has taken place- but somehow internally the EF disregards my actual values and writes truncated latitude/longitude rounded to ONLY TWO decimal digits, so my Latitude shows in the DB as 09.500000000 all other decimal digits are zeroed because a rounding seems to have taken place.

// Prior to SaveChanges()
Latitude = 9.08521879
Longitude = -79.51658792
// After SaveChanges()
Latitude = 9.08000000
Longitude = -79.51000000

Why is it rounding it if I have given the correct scale and precision and the column has the correct scale and precision as well? why is SaveChanges altering my values?

I found this post (http://weiding331.blogspot.com/2014/01/entity-framework-decimal-value.html) which is the same issue but I don't know how I can fix that (if it does) because I have already performed several migrations and data additions after the table in question was "migrated".

Summarizing

  • The model data type is correct (decimal)
  • The database migration code has the correct precion/scale (lat 10/8 lon 11/8)
  • The SQL database columns have the correct precision/scale (lat 10/8, long 11/8)
  • The values passed in the model have at least 8 decimal digits for both latitude and longitude
  • the actual writing/updating of the value takes place in the database without error, but...
  • The values recorded on the database for these two columns are truncated to TWO decimal digits and show the other least significant decimal digits as zero (0)

解决方案

EF has a special property for SqlProviderServices (implementation for the SqlClient provider for SQL Server) - TruncateDecimalsToScale. The default value is true so maybe you can change it to false value. For example:

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

    [DbConfigurationType(typeof(DbContextConfiguration))]
    public class MyContext : DbContext
    { ... }

More info about that: https://msdn.microsoft.com/en-us/library/system.data.entity.sqlserver.sqlproviderservices.truncatedecimalstoscale%28v=vs.113%29.aspx

这篇关于实体框架代码首先截断我的小数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆