C# 动态 LINQ:在字典索引器上使用“总和”进行选择
本文关键字:总和 选择 行选 LINQ 动态 字典 索引 | 更新日期: 2023-09-27 18:35:49
我正在使用动态 LINQ 创建分组依据并即时选择。我的项是键/值集合(字典),因此它们不包含任何属性(这是设计要求,无法更改)。我能够在另一个问题中解决分组部分,但它似乎在选择方法中不起作用。
我的代码如下:
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(value)" : ParseException: 表达式预期
"Sum(''"value''")" : ParseException: 预期的表达式
"Sum(it[''"value''"])":ParseException:不存在适用的聚合方法"Sum"
"Sum(it[value])":ParseException:类型"字典"中不存在属性或字段"值"
"Sum([''"value''"])":解析异常:预期的表达式
但都失败了。有什么想法吗?
谢谢!肖恩
>我自己也遇到过这个问题;问题是Sum()
将列视为类型 object
(可以应用于Convert()
,甚至可以应用于Max()
,但不能应用于Sum()
),因此失败了; 请注意,它说没有适用的聚合函数。
解决方案是使用整数的内联转换。动态 LINQ 支持此转换,可以在您的示例中按如下方式完成:
selectSB.Append("Sum(")
.Append("Convert.ToInt32(") // Add this...
.Append("it['"")
.Append(name)
.Append("'"]")
.Append(")") // ... and this
.Append(") as ")
.Append(name);
如果您的列不是int
类型,我相信ToInt64
(bigint
)有效,以及ToDouble()
和ToDecimal()
。
你有正确的语法(我的测试字段是"一"和"二")
new ( Key.One, Sum(it["Two"]) as Two )
但是没有linq方法Sum(object),你需要告诉它它是什么Summing(int,float,decimal 等)
最简单的方法是将字典定义更改为 Dictionary<'string, int>假设您正在对整数求和。