根据条件使用linq在数据表中求和值

时间:2015-04-23 08:07:34

标签: c# asp.net linq

我有一个如下所述的数据表。

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中做到这一点,我认为这是最好的方式。

3 个答案:

答案 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分组?然后查看GroupBySum

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));

现在,您可以使用AnyFirstOrDefaultforeach循环来使用此查询,以便执行以下操作之一:

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)));
}