我目前正在从 SQL Server 存储过程中读取数据,它以 Decimal(38, 20)
的形式返回。
我知道 .Net 小数是 (28, 10)
,但 EF 为此生成的模型类显示 Decimal?
。当我查询表时,代码抛出一个转换溢出错误,因为它试图将 SQL Server 小数点放在 .Net 小数点字段中。
是否有一种简单的方法可以通过数据上下文将其转换为.Net 十进制?基本上我无权修改 SQL Server 数据类型。
SQL Server 数据类型:
Amount Decimal(38, 20)
实体
public class EntityClass
{
public decimal? Amount { get; set; }
}
当我调用
var eee = _context.EntityClass
.Select(x => x.Amount)
.FirstOrDefaultAsync();
我明白了
Conversion Overflow Error
最佳答案
这是 .NET 的 SqlClient 的错误或限制。这是一个重现:
using (var con = new SqlConnection("server=.;database=tempdb;Integrated Security=true"))
{
con.Open();
var cmd = new SqlCommand("select cast(4210862852.86 as decimal(38,20)) val", con);
using (SqlDataReader rdr = cmd.ExecuteReader())
{
rdr.Read();
var val = rdr.GetDecimal(0);
Console.WriteLine(val);
}
}
问题是这个数字
select cast(cast(4210862852.86 as decimal(38,20)) as varbinary(20))
存储并通过网络传输
0x261400010000D877FB4DEE8B51699A5005000000
并且 SqlClient 将拒绝转换最后 4 个字节中任何非零的小数:
internal decimal Decimal
{
get
{
ThrowIfNull();
if (StorageType.Decimal == _type)
{
if (_value._numericInfo.data4 != 0 || _value._numericInfo.scale > 28)
{
throw new OverflowException(SQLResource.ConversionOverflowMessage);
}
return new decimal(_value._numericInfo.data1, _value._numericInfo.data2, _value._numericInfo.data3, !_value._numericInfo.positive, _value._numericInfo.scale);
}
if (StorageType.Money == _type)
{
long l = _value._int64;
bool isNegative = false;
if (l < 0)
{
isNegative = true;
l = -l;
}
return new decimal((int)(l & 0xffffffff), (int)(l >> 32), 0, isNegative, 4);
}
return (decimal)this.Value; // anything else we haven't thought of goes through boxing.
}
}
我在这里针对 .NET Core 打开了一个问题:https://github.com/dotnet/corefx/issues/37592
关于c# - SQL Server to .Net Decimals with EF6 database first issue,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56065752/