首页 文章

C#Dynamic LINQ:在词典索引器上选择Sum

提问于
浏览
3

我'm using dynamic LINQ to create a groupby and select on the fly. My items are key/value collections (dictionaries) so they contain no properties (it'是一个设计要求,不能改变) . 我能够在another question中解决groupby部分,但它似乎不适用于select方法 .

我的代码如下:

private void GetValuesGroupedBy(List<Dictionary<string, object>> list, List<string> groupbyNames, List<string> summableNames)
    {
        // build the groupby string
        StringBuilder groupBySB = new StringBuilder();
        groupBySB.Append("new ( ");
        bool useComma = false;
        foreach (var name in groupbyNames)
        {
            if (useComma)
                groupBySB.Append(", ");
            else
                useComma = true;

            groupBySB.Append("it[\"");
            groupBySB.Append(name);
            groupBySB.Append("\"]");
            groupBySB.Append(" as ");
            groupBySB.Append(name);
        }
        groupBySB.Append(" )");

        // and now the select string
        StringBuilder selectSB = new StringBuilder();
        selectSB.Append("new ( ");
        useComma = false;
        foreach (var name in groupbyNames)
        {
            if (useComma)
                selectSB.Append(", ");
            else
                useComma = true;

            selectSB.Append("Key.")
                //.Append(name)
                //.Append(" as ")
                .Append(name);
        }
        foreach (var name in summableNames)
        {
            if (useComma)
                selectSB.Append(", ");
            else
                useComma = true;

            selectSB.Append("Sum(")
                .Append("it[\"")
                .Append(name)
                .Append("\"]")
                .Append(") as ")
                .Append(name);
        }
        selectSB.Append(" )");

        var groupby = list.GroupBy(groupBySB.ToString(), "it");
        var select = groupby.Select(selectSB.ToString());
    }

选择字符串的关键部分是正常的,但Sum部分不起作用 . 假设我想要的键叫做值,我试过:

  • “Sum(value)”:ParseException:预期的表达式

  • “Sum(\”value \“)”:ParseException:预期的表达式

  • “Sum(it [\”value \“])”:ParseException:没有适用的聚合方法'Sum'存在

  • “Sum(it [value])”:ParseException:类型'Dictionary'中不存在属性或字段'value'

  • “Sum([\”value \“])”:ParseException:预期的表达式

但都失败了 . 有任何想法吗?

谢谢!肖恩

2 回答

  • 2

    我亲自面对这个问题;问题是 Sum() 将列视为 object 类型(可以应用于 Convert() ,或 Max() 偶数,但不是 Sum() ),因此失败;请注意,它表示没有 applicable 聚合函数 .

    解决方案是使用内联转换为整数 . 动态LINQ支持此转换,可以在您的示例中按如下方式完成:

    selectSB.Append("Sum(")
        .Append("Convert.ToInt32(") // Add this...
        .Append("it[\"")
        .Append(name)
        .Append("\"]")
        .Append(")") // ... and this
        .Append(") as ")
        .Append(name);
    

    如果您的列不是 int 类型,我相信 ToInt64bigint )可用,以及 ToDouble()ToDecimal() .

  • 0

    你有正确的语法(我的测试字段是“一个”和“两个”)

    new ( Key.One, Sum(it["Two"]) as Two )
    

    但是没有linq方法Sum(对象),你需要告诉它它是什么Summing(int,float,decimal等)

    最简单的方法是将字典定义更改为Dictionary <'string,int>,假设您要求求整数 .

相关问题