我整天都在撞墙,试图弄清楚为什么会发生这种情况以及如何解决这个问题。我正在构建一个C#.NET MVC Web应用程序。我使用数据库中的Linq调用查询,如下所示:
calibHistory = db.CalibrationHistory
.Where(d => d.ID == EquipmentId && d.ChangeNum == maxChangeNum).First();
使用以下精度获取C#double类型(相当于SQL中的float):
2.3980000019073486
我将此对象绑定到局部视图中的表单。这很有效。但是,在Razor渲染中发生了一些事情,导致以下值四舍五入到:
2.39800000190735
显然,Razor正在将最后两位数字(最后两位数字从4位变为5位)四舍五入。调试显示Razor 知道正确的值 - 在保持double的模型中,您会看到具有完全精度的double。然而,在这里,事情变得有趣:SQL Server Management Server中的调用显示 Razor 值具有正确的精度not the double returned by Linq。
所以不知何故,Linq比SQL Server提供的更精确。我希望能够将表单中的发布值与上面的Linq查询进行比较,看看是否有更改。我还没有能够解决这个问题,所以任何帮助都会非常感激。
TL; DR:Linq正在为双打返回更高的精确度并搞乱平等措施。想要修复Linq查询或使Razor显示完全精确度。
答案 0 :(得分:1)
好的,感谢所有回答的人 - 惊讶有多少人在监控这些标签!
似乎我一直都有答案,但没有完全执行它。我已经使用过R格式说明符,但没有在我的数据注释中部署正确的变量组合。
由于EntityFramework的性质,我需要覆盖生成的POCO对象的某些方面。这使我得到了这个解决方案:
[MetadataType(typeof(CalibrationHistory.MetaData))]
public partial class CalibrationHistory
{
internal class MetaData {
[Display(Name = "New Sensor Calibration value")]
[DisplayFormat(DataFormatString ="{0:R}", ApplyFormatInEditMode = true)]
public double Sensor_Calib;
[Display(Name = "New Cylinder to Wall Distance value")]
[DisplayFormat(DataFormatString = "{0:R}", ApplyFormatInEditMode = true)]
public double Cylinder_to_Wall_Distance;
}
public override bool Equals(object obj)
{
CalibrationHistory castedObject = (CalibrationHistory)obj;
if (this.ID == castedObject.ID && this.Cylinder_to_Wall_Distance == castedObject.Cylinder_to_Wall_Distance
&& this.Sensor_Calib == castedObject.Sensor_Calib)
{
return true;
}
else {
return false;
}
}
在数据注释中,我只指定了一个DataFormatString 而没有的ApplyFormatInEditMode。因此,更改未反映在文本框中,因此不会以所需的精度发布。
谢谢大家的回答。
答案 1 :(得分:0)
Razor本身并不操纵数字。如果它正在呈现数字,则除非您另行指定,否则它将使用默认的.ToString()
方法。您可以尝试在部分视图中添加显式.ToString()
,使用格式字符串添加,无论此值呈现在何处。
就比较再次发布时的价值而言,您需要一些比#34; a = b"更复杂的代码。因为在比较非常小的数字时,double
数据类型会变得很糟糕。请参阅here。
非常可能您的号码2.3980000019073486不是存储在数据库中的确切值,因为double
只是精确to about 15-16 digits。如果需要更高的精度,请考虑将数据库的类型更改为十进制,以及相应的代码。 Decimal
精确到28-29位。