我'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 回答
我亲自面对这个问题;问题是
Sum()
将列视为object
类型(可以应用于Convert()
,或Max()
偶数,但不是Sum()
),因此失败;请注意,它表示没有 applicable 聚合函数 .解决方案是使用内联转换为整数 . 动态LINQ支持此转换,可以在您的示例中按如下方式完成:
如果您的列不是
int
类型,我相信ToInt64
(bigint
)可用,以及ToDouble()
和ToDecimal()
.你有正确的语法(我的测试字段是“一个”和“两个”)
但是没有linq方法Sum(对象),你需要告诉它它是什么Summing(int,float,decimal等)
最简单的方法是将字典定义更改为Dictionary <'string,int>,假设您要求求整数 .