2017-09-05 32 views
0

双重如果我有一个POCO类乘小数和Linq中

public class Entry 
{ 
    public double Quantity { get; set; } 
    public decimal Cost{ get; set; } 
} 

我如何做算术它们在LINQ查询的东西,如

context.Entries.Sum(e => (decimal)e.Quantity * e.Cost); 

我得到无法转换对象类型'System.Double'键入'System.Decimal'

编辑:我已经将小数转换为双倍,它的工作原理。

context.Entries.Sum(e => e.Quantity * (double)e.Cost); 
+0

我没有看到这个异常调用'.SUM()'用几个手动构造'Entry'实例阵列上。你有异常的堆栈跟踪吗?更多可以提供的代码上下文? – BACON

+1

按运算符优先级'数量'应该转换为十进制并乘以'Cost'(注意:如果您的查询是LINQ to Entities,请使用'AsEnumerable')。你能提供例外细节和堆栈跟踪吗? –

+0

只是一个想法(我知道它并不真正提供答案):你可以通过将数据库中的逻辑存储在存储过程中解决该问题,这可以使用linq执行。 – MarcinJuraszek

回答

0

,如果你使用的不是enumrable收集

context.Entries.ToList().Sum(d => Convert.ToDecimal(d.Quantity)*d.Cost) 
+0

如果OP的查询是LINQ to Entities(不能识别'ToDecimal'方法),这可能不起作用。在Sum之前使用'AsEnumerable'来保证安全。 –

+0

@TetsuyaYamamoto同意更新了答案 – jitender

3

实体框架可以使用Convert.ToDecimal()

context.Entries.Sum(d => Convert.ToDecimal(d.Quantity)*d.Cost) 

Here is working fiddle

编辑由山本哲也表示表明它不支持你想要的转换原来的查询,你可以进行以下修改:

context.Entries 
.AsEnumerable() // perform rest of work in memory 
.Sum(e => (decimal)e.Quantity * e.Cost); 
+1

这会将该表中的所有数据存入内存!你至少应该进行一次投影,以只抓取要添加在一起的列。 – MarcinJuraszek

+0

@MarcinJuraszek OP不想要投影,如果是这样,他只需添加一个Where子句。他的实体模型只有两个字段,所以我认为不需要过滤列。 – msd

+1

不,这个查询比较复杂,我已经简化了一下提问。我真的不想在记忆中这样做。 –

0

如果你坚持在数据库端执行所有的计算,你必须拥有铸造的问题,你可以使用SqlFunctions类的静态方法,但当然,这将有性能开销:

var result = context.Entries 
    .Sum(x => SqlFunctions.Exp(SqlFunctions.Log(x.Quantity) + SqlFunctions.Log(x.Cost))); 

说明:E 1(LN(数量)+ LN(成本))= E ^(LN(数量*成本))=数量* 成本

或者你可以尝试手动编写查询:

var result = context.Database 
    .SqlQuery<decimal>("select sum(Quantity * Cost) from dbo.Entries)").FirstOrDefault();