如何在Linq中将十进制转换为实数

时间:2017-01-24 13:04:01

标签: c# entity-framework linq

假设我们有表T,它有两列A和B,分别有浮点数和货币类型。我想编写一个linq查询,如下面的T-SQL语句:

Select A, B, A * B as C 
From SomeTable
Where C < 1000

我试着像下面那样施展

var list = (from row in model.Table 
            where ((decimal)row.A) * row.B < 1000 
            select new { A = row.A,
                         B = row.B ,
                         C = ((decimal)row.A) * row.B}
           ).ToList();

但它不允许强制转换操作。它抛出异常:

  

Linq to Entity查询不支持强制转换为十进制,因为   无法推断出所需的精度和尺度信息。

我的问题是如何在Linq中将double转换为十进制?我不想从数据库中获取数据 的更新
我注意到转换十进制为double工作但反向操作抛出异常。所以,
为什么我们不能将double转换为十进制? Sql服务器也在t-sql中执行相同的机制吗?它不会影响精度吗?

2 个答案:

答案 0 :(得分:3)

float(double)和decimal之间的区别在于float是精确的十进制。如果你给浮点值一个10.123的值,那么在内部它可以有一个值10.1229999999999,它非常接近10.123,但不完全是。

精度为x十进制的小数在第x个小数之前始终是准确的。

您的数据库的设计者认为类型A不需要十进制精度(或者他只是粗心大意)。给出计算结果比输入参数更精确是没有意义的。

如果您确实需要将结果转换为小数,请将公式计算为float / double,并在AsEnumerable之后强制转换为十进制:

(我对你的语法不太熟悉,所以我将使用扩展方法语法)

var list = model.Table.Where(row => row.A * row.B < 1000)
    .Select(row => new
    {
        A = row.A,
        B = row.B,
    })
    .AsEnumerable()
    .Select(row => new
    {
        A = row.A,
        B = row.B,
        C = (decimal)row.A * (decimal)row.B,
    });

含义:

  • 从我的表中,只获取值为row.A * row.B的行 &LT; 1000。
  • 从每个选定的行中,选择A列和B列中的值。
  • 将这两个值传输到本地内存(= AsEnumerable),
  • 为每个传输的行创建一个具有三个属性的新对象:
    • A和B具有转移的值。
    • C获得转移的A和B的十进制值的乘积

答案 1 :(得分:0)

您可以避免AsEnumerable()向Entity解释您想要多少小数位数。

var list = (from row in model.Table 
            where ((decimal)row.A) * row.B < 1000 
            select new { A = row.A,
                         B = row.B ,
                         C = (((decimal)((int)row.A)*100))/100) * row.B}
           ).ToList();