我有一个如下所述的数据表。
ID Percentage
1 50
1 30
2 0
2 100
结果:
ID Percentage
1 80
2 100
我尝试了这个并且它不起作用
var n = dt.AsEnumerable()
.Where(r => (int)r["ID"] != "0" || (int)r["ID"] != "100")
.Sum(r => (int)r["Percentage"]);
我是linq的新手,请提供一些建议。
现在我需要将每个ID的百分比相加,每个ID的百分比应为0或100%。
如果表中的任何一个ID没有0或100,我需要提醒。请问我如何在linq中做到这一点,我认为这是最好的方式。
答案 0 :(得分:2)
var result = from row in dt.AsEnumerable()
group row by row["ID"]
into g
select new
{
ID = g.Key,
Sum = g.Sum(x => int.Parse(x["Percentage"].ToString()))
};
var errorItems = result.Where(x => x.Sum != 100 && x.Sum != 0);
if (errorItems.Any())
{
var ids = errorItems.Select(x => x.ID);
string msg = string.Format("ID(s): [{0}] don't meet condition.", string.Join(",", ids));
MessageBox.Show(msg);
}
答案 1 :(得分:2)
你没有尝试得到"百分比"对于整个表格,所以直接对它进行总结不会给你想要的结果。
您正在尝试查找每个ID值的百分比总和,因此您需要按ID对其进行分组。
这是GroupBy(g => g.Field<int>("ID"))
的作用。然后你取组(g),对于每个组,你总计&#34;百分比&#34;成员专栏,...... Select(g => g.Sum(p => p.Field<int>("Percentage")))
以下是完整的代码。
dt.AsEnumerable().Where(r => r.Field<int>("ID") == 0 || r.Field<int>("ID") == 100).GroupBy(g => g.Field<int>("ID")).Select(g => g.Sum(p => p.Field<int>("Percentage")));
发出警告消息,您可以使用Any而不是检查值是否存在的位置
if(dt.AsEnumerable().Any(r => r.Field<int>("ID") != 0 && r.Field<int>("ID") != 100)
{
Console.WriteLine("Alert");
}
答案 2 :(得分:1)
我想你想要一个新的DataTable
列与第一列相同,但按ID分组?然后查看GroupBy
和Sum
:
var groupQuery = dt.AsEnumerable()
.Select(r => new { ID = r.Field<int>("ID"), Percentage = r.Field<int>("Percentage") })
.Where(x => x.ID != 0 && x.ID != 100)
.GroupBy(x => x.ID);
DataTable groupingTable = dt.Clone(); // empty, same columns
foreach(var grp in groupQuery)
groupingTable.Rows.Add(grp.Key, grp.Sum(x => x.Percentage));
这假设列的类型实际上是int
。如果它们是字符串,最好的方法是将其更改为int
,如果您不能这样做,则必须使用int.Parse
。
例如:
ID = int.Parse(r.Field<int>("ID"))`
更新:虽然如果我重新阅读你的qustion,你还不清楚你想要什么,尤其是:
如果表格中的任何一个ID没有0或100,我需要提醒
您可以使用它来获取没有0或100%的所有ID组:
var without0Or100Perc = dt.AsEnumerable()
.Select(r => new { ID = r.Field<int>("ID"), Percentage = r.Field<int>("Percentage") })
.GroupBy(x => x.ID)
.Where(g => !g.Any(x => x.Percentage == 0 || x.Percentage == 100));
现在,您可以使用Any
,FirstOrDefault
或foreach
循环来使用此查询,以便执行以下操作之一:
bool anyWithout0Or100Perc = without0Or100Perc.Any();
var firstWithout0Or100Perc = without0Or100Perc.FirstOrDefault();
anyWithout0Or100Perc = firstWithout0Or100Perc != null;
foreach (var grp in without0Or100Perc)
{
Console.WriteLine("ID: {0} Percentages:{1}",
grp.Key,
String.Join(",", grp.Select(x => x.Percentage)));
}