【发布时间】:2016-08-23 05:50:33
【问题描述】:
我的代码是这样的。
public class MyDbContext : DbContext
{
public virtual DbSet<CurrentData> CurrentData { get; set; }
}
public class CurrentData
{
public int ID { get; set; }
public DateTime Time { get; set; }
public float Value { get; set; }
}
...
float f = 1.37E-40f;
using (var context = new MyDbContext())
{
var data = new CurrentData() { ID = 100, Time = DateTime.Now, Value = f };
context.CurrentData.Add(data);
var result = context.SaveChanges();
}
它在SaveChanges() 上引发异常,因为浮点值很小。
传入的表格数据流 (TDS) 远程过程调用 (RPC) 协议流不正确。参数 4 (\"@1\"):提供的值不是真实数据类型的有效实例。检查源数据中的无效值。一个无效值的例子是小数位数大于精度的数值类型数据。
如果我将f 更改为0,它可以正常工作。
当我检查 SQL Server 的 REAL 类型范围时,最小正值为 1.18E-38。
https://msdn.microsoft.com/en-us/library/ms173773.aspx
所以如果C#中的float值小于1.18E-38,就会发生异常。
我像这样更改了f 值
if (f > 0 && f < 1.18E-38f)
f = 0;
else if (f < 0 && f > -1.18E-38f)
f = 0;
但我觉得不好看。
什么是更好的解决方案?
我使用SqlDataAdapter 而不是实体框架进行了测试,得到了同样的异常。
我在 SQL Server 2012 中使用了 EF v6.1.3 和 .NET 4.5.1。
【问题讨论】:
-
如果你只存储“数字”而不需要计算mssql中的数字,你也许可以将它存储为字符串文字? msdn.microsoft.com/en-us/library/sd9e25kz(v=vs.110).aspx
-
@montewhizdoh 因为没有必要这样做。 SQL Server 确实具有具有明确定义的比例和精度的
numeric类型,例如numeric(19,5)。 -
只是不要使用
float或real。在表上使用具有所需比例和精度的数字类型,在类上使用decimal。另一方面,为什么要使用这么小的数字?你想模拟一个 NULL 吗? -
@Panagiotis 你将如何存储 numeric(800,799) ?你没做过很多回归计算吧?
-
@montewhizdoh 我不知道。我询问了这种奇怪要求的原因。 OP 很可能正在尝试解决不同的问题,并认为存储一个小浮点数是解决方案。例如,代码和/或数据库不使用十进制/数字导致缩放错误。 OP 可能不得不使用一个小值而不是 0 进行比较。 real 解决方法是为所有数字字段定义适当的比例,并在需要时与 0 进行比较
标签: c# sql-server entity-framework