连接两个具有公共字段的数据表

Join two data tables having common fields

我有 2 个 datatable objects (dt1,dt2),它们有一个共同的字段,叫做 "File_Name"。我想创建一个 datatable (dtFinal),结合两个数据表以用于 asp.net

的 gridview

每个表 (dt1,dt2) 都可以有重叠的列 header 名称,这意味着如果 dt1 有一个 header 作为 "plant_code" dt2 也可以将 header 作为 "plant_Code" 但不是强制性的。

我的 objective 将拥有一个公共数据表 (dtFinal),其中包含来自所有单独数据表的所有 header。

我试过这样的东西

  Dt1.PrimaryKey = New DataColumn() {Dt1.Columns(System.AppDomain.CurrentDomain.BaseDirectory & "\resources\files\" & "GRN" & ".csv")}
  Dt2.PrimaryKey = New DataColumn() {Dt1.Columns(System.AppDomain.CurrentDomain.BaseDirectory & "\resources\files\" & "Payment Data" & ".csv")}
  Dt1 = CsvToDataTable(System.AppDomain.CurrentDomain.BaseDirectory & "\resources\files\" & "GRN" & ".csv")
  Dt2 = CsvToDataTable(System.AppDomain.CurrentDomain.BaseDirectory & "\resources\files\" & "Payment Data" & ".csv")


  ds.Tables.Add(Dt1)
  ds.Tables.Add(Dt2)

  Dim drel As New DataRelation("EquiJoin", Dt2.Columns("File_Name"), Dt1.Columns("File_Name"))

  ds.Relations.Add(drel)

  Dim jt As New DataTable("Joinedtable")
  ds.Tables.Add(jt)
  For Each dr As DataRow In ds.Tables("Table1").Rows

      Dim parent As DataRow = dr.GetParentRow("EquiJoin")
      Dim current As DataRow = jt.NewRow()
      ' Just add all the columns' data in "dr" to the New table.

      For i As Integer = 0 To ds.Tables("Table1").Columns.Count - 1
          current(i) = dr(i)
      Next
      ' Add the column that is not present in the child, which is present in the parent.
      current("Dname") = parent("Dname")
      jt.Rows.Add(current)
  Next

  DtFinal = ds.Tables("Joinedtable")

正在创建一个 dataset 以及 dt1 和 dt2 之间的关系...但这似乎不起作用并且在第 1 行 instance of object to be declared using New 中给我一个错误。

有人在 Vb 中尝试过类似的东西吗?或者可以编辑我的代码以使其工作。

更多信息:每个数据表 tb1 和 tb2 在第一列的 File_Name 列中都有唯一值。因此可以选择为主键。

您可以尝试数据表合并。

dt3 = new DataTable();

dt3 .Merge(dtOne);
dt3 .Merge(dtTwo);

查看此 post 了解更多 info/solutions。 Merge 2 DataTables and store in a new one

当您说 "Merge" 时,它可能意味着一件事或另一件事。比如我可能会想到这个方法

这是工作代码:

Public Sub  MergeTables()
    Dim t1 As New DataTable("T1")
    t1.Columns.Add("C1", GetType(String))
    t1.Columns.Add("C2", GetType(String))
    t1.Columns.Add("C3", GetType(String))

    Dim t2 As New DataTable("T2")
    t2.Columns.Add("C1", GetType(String)) 'same column
    t2.Columns.Add("C2", GetType(Integer)) ' same column, different data type
    t2.Columns.Add("C4", GetType(String)) ' different column

    Dim map As New Dictionary(Of String, String)

    Dim t3 As New DataTable("T4")
    MergeColumns(t3, t1, map)
    MergeColumns(t3, t2, map)

    Debug.WriteLine("Should be 5 columns and reality is: " & t3.Columns.Count)

    ' Add some data
    t1.Rows.Add({"data from t1 c1", "data from t1 c2", "data from t1 c3"})
    t2.Rows.Add({"data from t2 c1", 55, "data from t2 c3"})

    MergeRows(t3, t1, map)
    MergeRows(t3, t2, map)
    t3.AcceptChanges()


    For Each row As DataRow In t3.Rows
        Debug.WriteLine(String.Join(";", row.ItemArray.Select(Function(o) o.ToString()).ToArray()))
    Next

End Sub


Private Sub MergeColumns(totbl As DataTable, fromtbl As DataTable, map As Dictionary(Of String, String))
    For Each c As DataColumn In fromtbl.Columns
        If Not totbl.Columns.Contains(c.ColumnName) Then
            totbl.Columns.Add(c.ColumnName, c.DataType)
            map.Add(c.Table.TableName & "_" & c.ColumnName, c.ColumnName)
        ElseIf Not totbl.Columns(c.ColumnName).DataType.Equals(c.DataType) Then
            totbl.Columns.Add(c.Table.TableName & "_" & c.ColumnName, c.DataType)
            map.Add(c.Table.TableName & "_" & c.ColumnName, c.Table.TableName & "_" & c.ColumnName)
        Else
            map.Add(c.Table.TableName & "_" & c.ColumnName, c.ColumnName)
        End If
    Next
End Sub

Private Sub MergeRows(totbl As DataTable, fromtbl As DataTable, map As Dictionary(Of String, String))
    For Each row As DataRow In fromtbl.Rows
        Dim newRow As DataRow = totbl.NewRow()
        For Each c As DataColumn In fromtbl.Columns
            newRow(map(fromtbl.TableName & "_" & c.ColumnName)) = row(c.ColumnName)
        Next
        totbl.Rows.Add (newRow) 
    Next

End Sub

结果:

data from t1 c1 ; data from t1 c2 ; data from t1 c3 ; ; data from t2 c1 ; ; ; 55 ; data from t2 c3

但也许,您还需要其他东西。然而,这是如何做这样的事情的好例子