LINQ聚合查询中两个字段的产品

时间:2009-09-01 15:09:51

标签: linq grouping field product

我需要计算两个字段的乘积之和。这将用于平均加权价格。 avgPrice =总和(价格*体积)/总和(体积)。 price1和price2都返回错误“指定的演员表无效。”

     var result3 = from sym in dataTableAsEnumerable()
                   group sym by new { symbol = sym["symbol"] } into grouped
                   select new
                   {
                      //             SYMBOL = sym.Field<string>("symbolCAN"),
                      SYMBOL = grouped.Key.symbol,
                      tradeTimeMin = grouped.Min(e => e["tradeTimeMin"]),
                      tradeTimeMax = grouped.Max(e => e["tradeTimeMax"]),
                      volume = grouped.Sum(e => (int)e["volume"] ),
                      price1 = grouped.Sum(e => (double)e["volume"] * (double)e["symbol"]) / grouped.Sum(e => (double)e["volume"]),
                      price2 = grouped.Sum(e => ( e.Field<decimal>("volume") * e.Field<decimal>("symbol")))


                   };

1 个答案:

答案 0 :(得分:0)

您遇到的问题与从DataRow中获取值有关。看起来volumeintsymboldouble,但在您的错误行中,您使用的是另一种类型。一个类似的例子就是尝试这样做:

object o = 3.0; // double
decimal m = (decimal)o;

这会失败,因为您尝试将double展开为decimal。另一方面,这很好用:

object o = 3.0; // double
double d = (double)o;
decimal m = (decimal)d;

要修复你的例子,你需要先将值转换为正确的类型,然后相应地进行转换(或者只是回退隐式转换):

    ...
    price = grouped.Sum(e => e.Field<int>("volume") * e.Field<double>("symbol")) /
            grouped.Sum(e => e.Field<int>("volume"))
    ...

或使用匿名类型使您的最终选择更具可读性:

...
let data = grouped.Select(e => new {
   Volume = e.Field<int>("volume"),
   Symbol = e.Field<double>("symbol")
})
select new
{
    ...
    price = data.Sum(x => x.Volume * x.Symbol) / data.Sum(x => x.Volume)
    ...
};