c#

时间:2017-02-13 06:13:59

标签: c# asp.net linq

这是我的第一个数据表dt

sscode  scons  cscons  cstagged
  A      10         2         20
  A      10         2         20
  B      10         2         40

这是我的第二个数据表dt1

Unit  sscode
A101     A 
A101     A
B101     B

我想要这个输出

Unit  scons  cscons  cstagged
A101     20      4         40

我在执行此查询时遇到错误。 这是我的代码

IEnumerable<DataRow> result = from data1 in dt.AsEnumerable() 
                             join data2 in dt1.AsEnumerable()
                             on data1.Field<string>("sscode") equals
                             data2.Field<string>("substation_code")
                             group data2.Field<string>("Unit") by new {unit= data2.Field<string>("Unit")} into grp
                             orderby grp.Key.unit
                             select new
                                 {
                                     unit = grp.Key.unit,
                                     sscons = grp.Sum(s => s.Field<string>("cscons")),
                                     cscons = grp.Sum(s => s.Field<string>("cscons")),
                                     cstagged = grp.Sum(s => s.Field<string>("cstagged"))
                                 };
                             result.CopyToDataTable();

2 个答案:

答案 0 :(得分:1)

您当前代码的问题是grp包含两个dataTable的集合,在这种情况下,您将无法直接从第一个DataTable获取项目。

如果我已正确理解你的问题,那么这应该给你预期的输出: -

var result = from data2 in dt2.AsEnumerable() 
             group data2 by data2.Field<string>("Unit") into g
             select new { Unit = g.Key, dt2Obj = g.FirstOrDefault() } into t3
             let filteredData1 = dt.AsEnumerable()
               .Where(x => x.Field<string>("sscode") == t3.dt2Obj.Field<string>("sscode"))
             select new
                   {
                       unit = t3.unit,
                       sscons = filteredData1.Sum(s => s.Field<int>("cscons")),
                       cscons = filteredData1.Sum(s => s.Field<int>("cscons")),
                       cstagged = filteredData1.Sum(s => s.Field<int>("cstagged"))
                   };

首先我们在第二个dataTable中按Unit进行分组(因为这是我们需要的组合)然后我们使用sscode投影整个对象来获取FirstOrDefault,在此之后,只需根据我们从分组sscode获得的值过滤第一个列表并投影项目。

检查Working Fiddle

答案 1 :(得分:1)

首先,您必须在组后选择,否则只选择分组字段 第二,你不能总和字符串。只有数字字段(int,double ...)

我不能熟练使用inline-linq语法,因此我已将其更改为方法链。

{{ 2}}

注意:请注意,在此查询中,您无法使用var result = dt.AsEnumerable() .Join(dt1.AsEnumerable(), data1 => data1.Field<string>("sscode"), data2 => data2.Field<string>("substation_code"), (data1, data2) => new {data1, data2}) .GroupBy(@t => new {unit = @t.data2.Field<string>("Unit")}, @t => @t.data1) .Select( grp => new { unit = grp.Key.unit, sscons = grp.Sum(s => s.Field<int>("sscons")), cscons = grp.Sum(s => s.Field<int>("cscons")), cstagged = grp.Sum(s => s.Field<int>("cstagged")) });

更新
由于我了解您的字段存储为字符串,因此您应使用CopyToDataTable

Convert.ToInt32

更新2
根据聊天 - 似乎值是十进制而不是整数:

grp.Sum(s => Convert.ToInt32(s.Field<string>("cscons"))