【问题标题】:datatable colum sum using linq in c#在c#中使用linq的数据表列总和
【发布时间】:2017-02-13 19:46:06
【问题描述】:

这是我的第一个数据表 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();

【问题讨论】:

  • 你能分享错误信息吗?
  • 在 (s => s.Field("cscons")) s 不包含 '' 的定义的情况下出错
  • 你在计算字符串的总和吗?
  • 是的,但我不知道默认情况下在 datattable 中是哪种数据类型
  • 默认数据表的数据类型是DataTable。

标签: c# asp.net linq


【解决方案1】:

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

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

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

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

检查Working Fiddle

【讨论】:

  • @Harshal - 您不能将 匿名类型 直接投影到数据表。您必须实现MSDNthis 中提到的自定义类型。顺便说一句,你能告诉我你为什么需要一个 DataTable 吗?
  • sscons 和以下的总和没有执行
  • @Harshal - 表现不一样?你有什么错误吗?我已经在我的系统上对其进行了测试,它对我来说运行良好。
  • @Harshal - 我不知道你在哪里得到错误,请检查我刚刚添加的小提琴,看看你错在哪里。
  • Sum(s => s.Field("cstagged") 指定的转换无效。
【解决方案2】:

首先,您必须在分组后选择,否则只会选择分组字段。
其次,您不能对字符串求和。只有数字字段(int、double...)

我不熟悉 inline-linq 语法,所以我将其更改为方法链。

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:

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

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

 sscons = grp.Sum(s => s.Field<decimal>("sscons")),
 cscons = grp.Sum(s => s.Field<decimal>("cscons")),
 cstagged = grp.Sum(s => s.Field<decimal>("cstagged"))

【讨论】:

  • 给出错误 指定转换对 Sum(s => s.Field("cscons")) 无效,
  • 那么,这些字段是什么类型的?如果它真的是字符串,那么你必须解析成整数。但最好首先将它们存储为 int 。将更新我的答案以添加转换为 int
  • 我在数据表中添加了列是 DataTable data = new DataTable(); data.Columns.Add("单位", typeof(string)); data.Columns.Add("sscons", typeof(int)); data.Columns.Add("cscons", typeof(int)); data.Columns.Add("cstagged", typeof(int));
  • 它仍然给你Specified cast is not valid?
  • @Harshal 有些奇怪。 Unitssconscscons 不在同一个表中,但在您上面的评论中,您似乎将这些字段添加到同一个 DataTable
猜你喜欢
  • 2014-02-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-07
  • 1970-01-01
相关资源
最近更新 更多