C# 如果ID匹配,如何合并数据表但合并行?

C# 如果ID匹配,如何合并数据表但合并行?,c#,datatable,C#,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

输入:

假设我有两个数据表。第一个:

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

您可以使用LINQ根据
ID
Date
连接两个数据表,然后使用如下方法将结果投影/加载到结果数据表中:

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);
DataTable dtResult=newdatatable();
var query=来自dt1.AsEnumerable()中的行1
在上的dt2.AsEnumerable()中加入行2
新的{ID=row1.Field(“ID”),Date=row1.Field(“Date”)}
等于
新的{ID=row2.Field(“ID”),Date=row2.Field(“Date”)}
选择dtResult.LoadDataRow(新对象[])
{
第1行。字段(“ID”),
第1行字段(“日期”),
第1行字段(“值A”),
第1行字段(“ValueB”),
第2行字段(“ValueC”),
第2行字段(“已估价”)
},假);

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

您可以使用LINQ根据
ID
Date
连接两个数据表,然后使用如下方法将结果投影/加载到结果数据表中:

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);
DataTable dtResult=newdatatable();
var query=来自dt1.AsEnumerable()中的行1
在上的dt2.AsEnumerable()中加入行2
新的{ID=row1.Field(“ID”),Date=row1.Field(“Date”)}
等于
新的{ID=row2.Field(“ID”),Date=row2.Field(“Date”)}
选择dtResult.LoadDataRow(新对象[])
{
第1行。字段(“ID”),
第1行字段(“日期”),
第1行字段(“值A”),
第1行字段(“ValueB”),
第2行字段(“ValueC”),
第2行字段(“已估价”)
},假);

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

您可以使用LINQ按分组,然后如果需要,将值放回数据表中:

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);
        }
var rows=dt.AsEnumerable()
。选择(s=>
刚出现的
{
ID=s.字段(“ID”),
日期=s.字段(“日期”),
ValueA=s.字段(“ValueA”)
})
.群比(
key=>new{key.ID,key.Date},
(键,agg)=>
刚出现的
{
key.ID,
关键日期,
ValueA=agg.Max(a=>a.ValueA)//等。
});
var分组=新数据表(“分组”);
foreach(行中的var r)
{
var row=grouped.NewRow();
//将现在所需的行放回数据表中
分组。行。添加(行);
}

您可以使用LINQ进行分组,然后在需要时将值放回数据表中:

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);
        }
var rows=dt.AsEnumerable()
。选择(s=>
刚出现的
{
ID=s.字段(“ID”),
日期=s.字段(“日期”),
ValueA=s.字段(“ValueA”)
})
.群比(
key=>new{key.ID,key.Date},
(键,agg)=>
刚出现的
{
key.ID,
关键日期,
ValueA=agg.Max(a=>a.ValueA)//等。
});
var分组=新数据表(“分组”);
foreach(行中的var r)
{
var row=grouped.NewRow();
//将现在所需的行放回数据表中
分组。行。添加(行);
}

谢谢,请投赞成票。但是如果我有一些可变数量的表,比如4或5,会怎么样?我是否必须多次这样做,即将1连接到2,然后将结果连接到3,然后将结果连接到4,等等?@user1032613,在这种情况下,我会将其提取到一个方法中,并将我的数据表传递到当前和下一个,然后获得一个
数据表
并将其合并。谢谢,请进行投票。但是如果我有一些可变数量的表,比如4或5,会怎么样?我是否必须多次执行此操作,即将1连接到2,然后将结果连接到3,然后将结果连接到4,等等?@user1032613,在这种情况下,我会将其提取到一个方法,并将我的datatables当前和下一个传递,然后返回一个
DataTable
,并合并它们。