小数位未正确舍入 - 这是 LINQ to SQL 错误吗?
我的数据库字段(sql server 2005)是用 numeric(15,2) 定义的。
LINQ 2 SQL 生成的属性是
[Column(Storage="_My_Property_Name", DbType="Decimal(15,2)", UpdateCheck=UpdateCheck.Never)]
public System.Nullable<decimal> My_Property_Name
{
get
{
return this._My_Property_Name;
}
set
{
if ((this._My_Property_Name != value))
{
this.OnMy_Property_NameChanging(value);
this.SendPropertyChanging();
this._My_Property_Name = value;
this.SendPropertyChanged("My_Property_Name");
this.OnMy_Property_NameChanged();
}
}
}
在调试中我检查此属性的实体值 = 23.6363636363 (等)
然后我跳过 context.SubmitChanges()
我正在运行 SQL Profiler,这是更新语句。
exec sp_executesql N'
UPDATE [Staging].[My_Table_Name]
SET [LAST_UPDATE_DATE] = @p2, [Field1] = @p3, [Field2] = @p4, [Field3] = @p5, [Field4] = @p6, [Field5] = @p7, [Field6] = @p8, [Field7] = @p9
WHERE ([Id] = @p0) AND ([RecordVersion] = @p1)
SELECT [t1].[RecordVersion] FROM [Staging].[My_Table_Name] AS [t1]
WHERE ((@@ROWCOUNT) > 0) AND ([t1].[Id] = @p10)',N'@p0 int,@p1 timestamp,@p2 datetime,@p3 decimal(21,8),@p4 decimal(21,8),@p5 decimal(21,8),@p6 decimal(21,8), @p7 decimal(21,8),@p8 decimal(21,8),@p9 decimal(15,2),@p10 int',@p0=2935,@p1=0x0000000000323018,@p2='2010-02-26 16:49:21:690', @p3=99.99992307,@p4=99.99992307,@p5=99.99992307,@p6=99.99992307,@p7=99.99992307,@p8=99.99992307,
@p9=23.63,@p10=2935
正如你所看到的 @p9 = 23.63,我预计它是 23.64。
更新
我的问题是,
如果这是一个 LINQ to SQL 错误,我希望它是一个已知错误,我在哪里可以找到它? 某处是否有维护的错误列表?
另外什么是最好的解决办法?
- 我猜想改变将字段更改为 15,3 不会修复该错误,它只会将其移动 1 位小数。
- 重写 OnMy_Property_NameChanged() 可以用于此属性,但我有很多这样的属性。
更新2
这也不起作用,它在submitchanges之前进入这段代码并且似乎起作用,但是生成的更新sql仍然具有截断的值,而不是这个更新的舍入值。
partial void OnMy_Property_Name_ChangingChanging(decimal? value)
{
if (!value.HasValue)
{
return;
}
value =
Math.Round(value.Value, 2, MidpointRounding.AwayFromZero);
}
我目前得到的修复只是直接更新实体值。
My database field (sql server 2005) is defined with numeric(15,2).
The LINQ 2 SQL generated property is
[Column(Storage="_My_Property_Name", DbType="Decimal(15,2)", UpdateCheck=UpdateCheck.Never)]
public System.Nullable<decimal> My_Property_Name
{
get
{
return this._My_Property_Name;
}
set
{
if ((this._My_Property_Name != value))
{
this.OnMy_Property_NameChanging(value);
this.SendPropertyChanging();
this._My_Property_Name = value;
this.SendPropertyChanged("My_Property_Name");
this.OnMy_Property_NameChanged();
}
}
}
In debug I check the entity value for this property = 23.6363636363 (etc)
I then step over context.SubmitChanges()
I have SQL Profiler running and this is the update statement.
exec sp_executesql N'
UPDATE [Staging].[My_Table_Name]
SET [LAST_UPDATE_DATE] = @p2, [Field1] = @p3, [Field2] = @p4, [Field3] = @p5, [Field4] = @p6, [Field5] = @p7, [Field6] = @p8, [Field7] = @p9
WHERE ([Id] = @p0) AND ([RecordVersion] = @p1)
SELECT [t1].[RecordVersion] FROM [Staging].[My_Table_Name] AS [t1]
WHERE ((@@ROWCOUNT) > 0) AND ([t1].[Id] = @p10)',N'@p0 int,@p1 timestamp,@p2 datetime,@p3 decimal(21,8),@p4 decimal(21,8),@p5 decimal(21,8),@p6 decimal(21,8), @p7 decimal(21,8),@p8 decimal(21,8),@p9 decimal(15,2),@p10 int',@p0=2935,@p1=0x0000000000323018,@p2='2010-02-26 16:49:21:690', @p3=99.99992307,@p4=99.99992307,@p5=99.99992307,@p6=99.99992307,@p7=99.99992307,@p8=99.99992307,
@p9=23.63,@p10=2935
As you can see @p9 = 23.63, I would expect it to be 23.64.
Update
My question is,
If this is a LINQ to SQL bug I would expect it to be a known one, where would I find this out; is there a maintained bug list somewhere?
Also what would be the best work around?
- I'm guessing changing the field to 15,3 wouldn't fix the bug, it would just shift it 1 decimal place.
- Overriding the OnMy_Property_NameChanged() would work for this property, but I have lots of them.
Update 2
this didn't work either, it goes into this piece of code before submitchanges and appears to work, but the generated update sql still has the truncated value, not this updated rounded value.
partial void OnMy_Property_Name_ChangingChanging(decimal? value)
{
if (!value.HasValue)
{
return;
}
value =
Math.Round(value.Value, 2, MidpointRounding.AwayFromZero);
}
The fix I've got at the moment is just to update the entity value directly.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
MSDN 说:
您可以通过重写 OnMy_Property_NameChanged() 并将其四舍五入来处理此问题。确保指定正确的舍入模式(到偶数或从零开始)。
MSDN says:
You could handle this via overriding
OnMy_Property_NameChanged()
and rounding it there. Make sure you specify the correct rounding mode (to even or from zero).在我看来,Link to SQL 似乎将值截断到小数点后两位,而不是四舍五入。
It looks to me as though Link to SQL is truncating the value to 2 decimal places instead of rounding it.
看来是LINQ的bug。您需要将DBType从
Decimal(15,2)
更改为Decimal(15,3)
。这比数据库中的列精度增加了 1 个精度。it seems the bug of LINQ. you need to change DBType from
Decimal(15,2)
toDecimal(15,3)
. That is increment 1 extra precision than your column precision in database.