Reputation: 36333
Input:
Say I have two DataTables. The first one:
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
The second one:
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
What I tried:
I tried to do DataTable1.Merge(DataTable2);
, but I get this:
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
Desired result:
I'd like to combine rows, if their ID and Date match.
I want this:
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
Upvotes: 2
Views: 4281
Reputation: 903
The above solution is missing a method to fill the datatable. it should be
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))
.CopyToDataTable();
the .CopyToDataTable(); is the magic keyword
Upvotes: 0
Reputation: 3256
You can use LINQ to group by, then put the values back into a DataTable if you need it that way:
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);
}
Upvotes: 1
Reputation: 223277
You can use LINQ to join the two DataTables based on ID
and Date
and then project/Load the results into a resultant DataTable using LoadDataRow
method like:
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);
Make sure that the types specified with Field
extension method matches with that of your columns in DataTable
.
Upvotes: 3