如果ID匹配,如何合并DataTables但合并行?

时间:2014-11-21 16:39:43

标签: c# datatable

输入:

说我有两个DataTable。第一个:

ID  Date    ValueA  ValueB
1   Nov.21  72.4    23.4
1   Nov.22  71.4    24.4
2   Nov.21  74.4    21.4

第二个:

ID  Date    ValueC  ValueD
1   Nov.21  42.4    53.4
1   Nov.22  41.4    54.4
2   Nov.21  44.4    51.4

我尝试了什么:

我尝试DataTable1.Merge(DataTable2);,但我明白了:

ID  Date    ValueA  ValueB  ValueC  ValueD
1   Nov.21  72.4    23.4    
1   Nov.22  71.4    24.4    
2   Nov.21  74.4    21.4    
1   Nov.21                  42.4    53.4
1   Nov.22                  41.4    54.4
2   Nov.21                  44.4    51.4

期望的结果:

如果他们的ID和日期匹配,我想要合并行。

我想要这个:

ID  Date    ValueA  ValueB  ValueC  ValueD
1   Nov.21  72.4    23.4    42.4    53.4
1   Nov.22  71.4    24.4    41.4    54.4
2   Nov.21  74.4    21.4    44.4    51.4

2 个答案:

答案 0 :(得分:3)

您可以使用LINQ基于IDDate加入两个DataTable,然后使用LoadDataRow方法将结果投影/加载到结果DataTable中:

DataTable dtResult = new DataTable();

var query = from row1 in dt1.AsEnumerable()
            join row2 in dt2.AsEnumerable() on
                new { ID = row1.Field<int>("ID"), Date = row1.Field<DateTime>("Date") }
                equals
                new { ID = row2.Field<int>("ID"), Date = row2.Field<DateTime>("Date") }
            select dtResult.LoadDataRow(new object[]
    {
        row1.Field<int>("ID"),
        row1.Field<DateTime>("Date"),
        row1.Field<double>("ValueA"),
        row1.Field<double>("ValueB"),
        row2.Field<double>("ValueC"),
        row2.Field<double>("ValueD")
    }, false);

确保使用Field扩展方法指定的类型与DataTable中的列匹配。

答案 1 :(得分:1)

您可以使用LINQ进行分组,然后在需要时将值重新放回DataTable中:

var rows = dt.AsEnumerable()
                    .Select(s =>
                        new
                        {
                            ID = s.Field<int>("ID"),
                            Date = s.Field<DateTime>("Date"),
                            ValueA = s.Field<int>("ValueA")
                        })
                    .GroupBy(
                        key => new { key.ID, key.Date },
                        (key, agg) =>
                        new
                        {
                            key.ID,
                            key.Date,
                            ValueA = agg.Max(a => a.ValueA) // etc.
                        });

        var grouped = new DataTable("grouped");

        foreach (var r in rows)
        {
            var row = grouped.NewRow();

            // Put the rows that are now as you want them back into a datatable

            grouped.Rows.Add(row);
        }