DataRows到DataTable

时间:2018-06-03 14:17:44

标签: c# .net-4.5

我想将两个DataTable合并为一个DataTable,问题是它没有主键。我有些人通过使用这个代码实现了它。

var result = (from t1 in table1.AsEnumerable()
                          join t2 in table2.AsEnumerable()
                          on table1.Rows.IndexOf(t1) equals table2.Rows.IndexOf(t2)
                          select  new { t1, t2 });

但我的结果是DataRow的匿名类型。我想将其转换为新的DataTable

2 个答案:

答案 0 :(得分:0)

您可以尝试使用linq Concat

var result = 
  (from t1 in table1.AsEnumerable() select t1).Concat
  (from t2 in table2.AsEnumerable() select t2);

如果您想过滤相同的值,可以使用Union

var result =
 (from t1 in table1.AsEnumerable() select t1).Union
  (from t2 in table2.AsEnumerable() select t2);

c#online:http://rextester.com/WUHC39800

答案 1 :(得分:0)

你的linq根本不会返回DataRow;它返回一个两个 DataRows的匿名元组。 (或者更确切地说是Enumarable

我认为你不能用简单的(或不那么简单的)linq创建一个新的DataRow

相反,您需要从新DataTable 创建该表后)创建行,然后逐个填充字段。

原因是DataRow没有有意义的构造函数。

要创建DataRow,您始终需要DataTable;然后可以编写一个函数:

DataRow MergeRows(DataTable dt, DataRow row1, DataRow row2)
{
    var row3 = dt.NewRow();

    for (int i = 0; i < row1.ItemArray.Length; i++)
    {
        row3.SetField(i, row1.ItemArray[i]);
    }
    int colCount1 = row1.ItemArray.Length;
    for (int i = 0; i < row2.ItemArray.Length; i++)
    {
        row3.SetField(i + colCount1 , row2.ItemArray[i]);
    }
    return row3;
}

这假设字段匹配。

要创建第3个DataTable,只需添加所有列;有方法可以使用DataTable.Merge(),但使用一个小帮助函数可能更简单:

List<DataColumn> MergeColumns(DataTable dt1, DataTable dt2)
{
  var cols = new List<DataColumn>();
  foreach (DataColumn c in dt1.Columns) cols.Add(new DataColumn(c.ColumnName, c.DataType));
  foreach (DataColumn c in dt2.Columns) cols.Add(new DataColumn(c.ColumnName, c.DataType));
  return cols;
}

并添加结果:

table3.Columns.AddRange(MergeColumns(table1, table2).ToArray());

现在您的linq可以更改为

 var result = (from t1 in table1.AsEnumerable()
                      join t2 in table2.AsEnumerable()
                      on table1.Rows.IndexOf(t1) equals table2.Rows.IndexOf(t2)
                      select MergeRows(table3, t1, t2) );

现在你可以从行创建第3个DataTable(再次!):

if (result.Count() > 0)
    table3 =  result.Cast<DataRow>().ToArray().CopyToDataTable();