[英]SQL Server DateTime Object and C# Datetime using Entity Framework
[英]Inserting small float value to SQL Server using C# and Entity Framework
我的代码是这样的。
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# 中的浮点值小于 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。
这里的问题是在 x86 体系结构上运行时,C# 支持非规范化浮点值,而 SQL Server 不支持。 因此,C# float
支持的值比 SQL Server REAL
,即使两者名义上都是单精度浮点类型。 (更令人困惑的问题是 SQL Server 调用FLOAT
实际上是一种双精度类型,C# 调用double
,所以float != FLOAT
—— 但这不是这里的问题)。
在 C# 中无法禁用非规范化值,也没有非常好的方法来测试它们。 不过,这个问题在答案中有一些方法。 另一种方法当然是将 SQL Server 端的列的精度提高到FLOAT
; 这可以处理 C# float
范围内的所有值,甚至是非规范化的。 当然,当您从数据库中读取不适合float
的值时,这只会转移问题。 当您需要存储 C# double
,它没有解决方案,因为在 SQL 端没有相应的更大的类型。
出于实际目的,一个简单的范围检查可能已经足够了,特别是如果您可以将它与您的应用程序实际使用的范围联系起来。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.