我有这个简单的数据表:
type (string) | cnt (int)
_____________________________________
aaa 1
aaa 2
aaa 10
bbb 1
bbb 1
我想生成 1 这样的匿名类型:
{
sumAAA= 13 , sumBBB=2 //13=1+2+10....
}
类似于:(伪代码)
var obj= dt.AsEnumerable().Select(f=> new { sumAAA =f.sumOfCntOfAaa , sumBBB =f.sumOfCntOfBbb });
任何帮助?
编辑,这将有助于你
DataTable dt = new DataTable("myTable");
dt.Columns.Add("cnt", typeof (int));
dt.Columns.Add("type", typeof (string));
DataRow row = dt.NewRow();
row["cnt"] = 1;
row["type"] = "aaa";
dt.Rows.Add(row);
row = dt.NewRow();
row["cnt"] = 2;
row["type"] = "aaa";
dt.Rows.Add(row);
row = dt.NewRow();
row["cnt"] = 10;
row["type"] = "aaa";
dt.Rows.Add(row);
row = dt.NewRow();
row["cnt"] = 1;
row["type"] = "bbb";
dt.Rows.Add(row);
row = dt.NewRow();
row["cnt"] = 1;
row["type"] = "bbb";
dt.Rows.Add(row);
答案 0 :(得分:6)
充满活力:
dynamic result = new ExpandoObject();
dt.AsEnumerable()
.GroupBy(r => r.Field<String>("type"))
.ToList()
.ForEach(g=> ((IDictionary<String, Object>)result)["sum" + g.Key.ToUpper()] = g.Sum(r=>r.Field<Int32>("cnt")));
Console.WriteLine(result.sumAAA);
Console.WriteLine(result.sumBBB);
适用于不同type
s的豁免号码,不仅适用于aaa
和bbb
。
<强>输出:强>
13
2
答案 1 :(得分:4)
在程序集中,具有相同属性且具有相同类型和顺序的所有匿名类型都是相同类型。因此,可以创建相同匿名类型的新实例:
第一版
var totals = new {
SumAs = 0,
SumBs = 0
};
var result = dt.AsEnumerable().Select(dr => {
totals = new {
SumAs = totals.SumAs + (dr["type"].Equals("aaa") ? (int)dr["cnt"] : 0),
SumBs = totals.SumBs + (dr["type"].Equals("bbb") ? (int)dr["cnt"] : 0)
};
return totals;
}).Last();
但是使用聚合可以做得更好......
第二版
var result2 = dt.AsEnumerable().Aggregate(new { SumAs = 0, SumBs = 0 }, (total, dr) => {
return new {
SumAs = total.SumAs + (dr["type"].Equals("aaa") ? (int)dr["cnt"] : 0),
SumBs = total.SumBs + (dr["type"].Equals("bbb") ? (int)dr["cnt"] : 0)
};
});
更新:使用版本2的完整示例
(使用元组,因为它们更容易设置):
粘贴到默认的C#控制台项目中:
using System;
using System.Linq;
class Program {
static void Main(string[] args) {
var input = Enumerable.Range(1, 10).Select(x => Tuple.Create(x, x*x));
var res = input.Aggregate(new { Firsts = 0, Seconds = 0}, (total, val) => {
return new {
Firsts = total.Firsts + val.Item1,
Seconds = total.Seconds + val.Item2
};
});
Console.WriteLine("Firsts: {0}; Seconds: {1}", res.Firsts, res.Seconds);
}
}
答案 2 :(得分:1)
你有什么理由不想使用2个LINQ语句吗?
var obj = new {
sumAAA = dt.Rows
.Where(x => x["type"] == "aaa")
.Sum(y => (int) y["cnt"]),
sumBBB = dt.Rows
.Where(x => x["type"] == "bbb")
.Sum(y => (int) y["cnt"])
};
还是一个简单的for循环?
int sAAA = 0; int sBBB = 0;
foreach (DataRow row in dt.Rows)
{
if(row["type"] == "aaa")
sAAA += (int) row["cnt"];
else
sBBB += (int) row["cnt"];
}
var obj = new { sumAAA = sAAA, sumBBB = sBBB };
编辑:哎呀...匿名对象是不可变的,相应地改变了我的答案
答案 3 :(得分:0)
var list = dt.AsEnumerable()
.GroupBy(row => row["type"])
.Select(grp => new { Type = grp.Key,
Sum = grp.Sum(c => (int)c["cnt"])
});
这将为您提供匿名{type,sum}的列表,这必须是一个好的开始!