none
Zusammenführen von 2 Datatables zu einer RRS feed

  • Frage

  • table 1

    id name zahl
    1   test  2
    2   test2 5
    3   test3 11


    table 2
    id name1 zahl2
    1   top1  22
    2   top2  23
    3   top3  24


    ich will nun durch Merge? folgendes Ergebnis in der Table haben

    1 test 2 top1 22
    2 test2 5 top2 23
    3 test3 11 top3 24

    oRet = Table1
    oRet1 = table2

    durch   oRet.Merge(oRet1, False)
    bekomme ich aber immer

    1 test 2
    2   test2 5
    3   test3 11
    4            top1  22
    5       top2  23 
    6             top3  24

    Dienstag, 21. Februar 2012 19:18

Antworten

  • Hallo Thomas Klinger2,

    Nochmals, dasselbe Ergebnis, mit anderem Code und mit LINQ to SQL:

     Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
            ''Table1******************************************************
            Dim tblA As New DataTable("table1")
    
            tblA.Columns.Add(New DataColumn("Id", GetType(Integer)))
            tblA.Columns.Add(New DataColumn("Name", GetType(String)))
            tblA.Columns.Add(New DataColumn("Zahl", GetType(Integer)))
    
            tblA.LoadDataRow(New Object() {1, "test", 2}, True)
            tblA.LoadDataRow(New Object() {2, "test2", 5}, True)
            tblA.LoadDataRow(New Object() {3, "test3", 11}, True)
            ''************************************************************
    
            ''Table2******************************************************
            Dim tblB As New DataTable("table1")
    
            tblB.Columns.Add(New DataColumn("Id", GetType(Integer)))
            tblB.Columns.Add(New DataColumn("Name1", GetType(String)))
            tblB.Columns.Add(New DataColumn("Zahl2", GetType(Integer)))
    
            tblB.LoadDataRow(New Object() {1, "top1", 22}, True)
            tblB.LoadDataRow(New Object() {2, "top2", 23}, True)
            tblB.LoadDataRow(New Object() {3, "top3", 24}, True)
            ''************************************************************
     
            Dim query = From A In tblA.AsEnumerable _
                  Join B In tblB.AsEnumerable On _
                  A.Field(Of Integer)("Id") Equals B.Field(Of Integer)("Id") _
                  Select New With { _
                  .Id = A.Field(Of Integer)("Id"), _
                  .Name = A.Field(Of String)("Name"), _
                  .Zahl = A.Field(Of Integer)("Zahl"), _
                  .Name1 = B.Field(Of String)("Name1"), _
                  .Zahl2 = B.Field(Of Integer)("Zahl2")}
    
            '//DataGridView1.DataSource = query.ToList()
    
            '//oder die query (IEnumerable) in einem DataTable konvertieren
            Dim tbl As DataTable = ObtainDataTableFromIEnumerable(query)
            DataGridView1.DataSource = tbl
        End Sub
    
        Private Function ObtainDataTableFromIEnumerable(ien As IEnumerable) As DataTable
            Dim dt As New DataTable()
            For Each obj As Object In ien
                Dim t As Type = obj.[GetType]()
                Dim pis As PropertyInfo() = t.GetProperties()
                If dt.Columns.Count = 0 Then
                    For Each pi As PropertyInfo In pis
                        dt.Columns.Add(pi.Name, pi.PropertyType)
                    Next
                End If
                Dim dr As DataRow = dt.NewRow()
                For Each pi As PropertyInfo In pis
                    Dim value As Object = pi.GetValue(obj, Nothing)
                    dr(pi.Name) = value
                Next
                dt.Rows.Add(dr)
            Next
            Return dt
        End Function

    Grüße,

    Robert


    Robert Breitenhofer, MICROSOFT  Twitter Facebook
    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    Freitag, 24. Februar 2012 10:42
    Moderator

Alle Antworten

  • Hallo Thomas,

    hast Du für beide Tabellen den Primärschlüssel zugewiesen?

    Siehe bspw.:

      http://msdn.microsoft.com/de-de/library/system.data.datatable.merge.aspx


    Gruß, Stefan
    Microsoft MVP - Visual Developer ASP/ASP.NET
    http://www.asp-solutions.de/ - Consulting, Development
    http://www.aspnetzone.de/ - ASP.NET Zone, die ASP.NET Community

    Dienstag, 21. Februar 2012 20:40
    Moderator
  • Hi Stefan,
    jetzt ja . Klappt aber leider auch nicht .
    Habe es so gemacht.

     

      Dim pk As DataColumn() = New DataColumn(0) {}
                                pk(0) = ds1.Tables(0).Columns("ID")
                                oRet.PrimaryKey = pk

                                Dim pk1 As DataColumn() = New DataColumn(0) {}
                                pk1(0) = ds2.Tables(0).Columns("ID")
                                oRet1.PrimaryKey = pk1
     oRet.Merge(oRet1, False)

    oRet ist Table1 (mit Daten)
    oRet1 ist Table2 (mit Daten)

    Habe aber immer noch 2 Rows. Die Anzahl der Columns in oRet ist schon mal korrekt.

                               

    Mittwoch, 22. Februar 2012 08:25
  • Hallo Thomas Klinger2,

    Schau Dir mal folgenden Code an. Vielleicht kann er Dir weiterhelfen.

    Public Class Form1
    
        Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    
            ''//table1****************************************************
            Dim tblA As New DataTable("table1")
            Dim dc1 As New DataColumn("Id", GetType(Integer))
            Dim dc2 As New DataColumn("Name", GetType(String))
            Dim dc3 As New DataColumn("Zahl", GetType(Integer))
            tblA.Columns.Add(dc1)
            tblA.Columns.Add(dc2)
            tblA.Columns.Add(dc3)
            Dim names() As String = {"test", "test2", "test3"}
            Dim theZahl() As Integer = {2, 5, 11}
            For i As Integer = 0 To names.Length - 1
                Dim dr As DataRow = tblA.NewRow
                dr("Id") = i + 1
                dr("Name") = names(i)
                dr("Zahl") = theZahl(i)
                tblA.Rows.Add(dr)
            Next
            ''//table1****************************************************
    
            ''//table2****************************************************
            Dim tblB As New DataTable("table2")
            Dim dc4 As New DataColumn("Id", GetType(Integer))
            Dim dc5 As New DataColumn("Name1", GetType(String))
            Dim dc6 As New DataColumn("Zahl2", GetType(Integer))
            tblB.Columns.Add(dc4)
            tblB.Columns.Add(dc5)
            tblB.Columns.Add(dc6)
            Dim names2() As String = {"top1", "top2", "top3"}
            Dim theZahl2() As Integer = {22, 23, 24}
            For i As Integer = 0 To names2.Length - 1
                Dim dr As DataRow = tblB.NewRow
                dr("Id") = i + 1
                dr("Name1") = names2(i)
                dr("Zahl2") = theZahl2(i)
                tblB.Rows.Add(dr)
            Next
            ''//table2****************************************************
    
            Dim tbl As DataTable
    
            Dim colsA() As String = {"Id", "Name", "Zahl"}
            Dim colsB() As String = {"Name1", "Zahl2"}
            Dim sKey As String = "Id"
    
    
            tbl = MergeData(tblA, tblB, colsA, colsB, sKey)
    
            DataGridView1.DataSource = tbl
        End Sub
    
       
        Private Function MergeData(ByVal tblA As DataTable, ByVal tblB As DataTable, _
                                  ByVal colsA() As String, ByVal colsB() As String, _
                                  ByVal sKey As String) As DataTable
    
            Dim tbl As DataTable
            Dim col As DataColumn
            Dim sColumnName As String
            Dim row As DataRow
            Dim newRow As DataRow
            Dim dv As DataView
    
            tbl = New DataTable
            dv = tblB.DefaultView
    
            For Each sColumnName In colsA
                col = tblA.Columns(sColumnName)
                tbl.Columns.Add(New DataColumn(col.ColumnName, col.DataType))
            Next
            For Each sColumnName In colsB
                col = tblB.Columns(sColumnName)
                tbl.Columns.Add(New DataColumn(col.ColumnName, col.DataType))
            Next
    
            For Each row In tblA.Rows
                newRow = tbl.NewRow
                For Each sColumnName In colsA
                    newRow(sColumnName) = row(sColumnName)
                Next
    
                dv.RowFilter = (sKey & " = " & row(sKey).ToString)
                If dv.Count = 1 Then
                    For Each sColumnName In colsB
                        newRow(sColumnName) = dv(0).Item(sColumnName)
                    Next
                End If
                tbl.Rows.Add(newRow)
            Next
    
            Return tbl
    
        End Function
    
    End Class

    Ergebnis:

    Merged_Data_Tables

    Grüße,

    Robert


    Robert Breitenhofer, MICROSOFT  Twitter Facebook
    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    Mittwoch, 22. Februar 2012 14:08
    Moderator
  • Hallo Thomas Klinger2,

    Nochmals, dasselbe Ergebnis, mit anderem Code und mit LINQ to SQL:

     Private Sub Button2_Click(sender As System.Object, e As System.EventArgs) Handles Button2.Click
            ''Table1******************************************************
            Dim tblA As New DataTable("table1")
    
            tblA.Columns.Add(New DataColumn("Id", GetType(Integer)))
            tblA.Columns.Add(New DataColumn("Name", GetType(String)))
            tblA.Columns.Add(New DataColumn("Zahl", GetType(Integer)))
    
            tblA.LoadDataRow(New Object() {1, "test", 2}, True)
            tblA.LoadDataRow(New Object() {2, "test2", 5}, True)
            tblA.LoadDataRow(New Object() {3, "test3", 11}, True)
            ''************************************************************
    
            ''Table2******************************************************
            Dim tblB As New DataTable("table1")
    
            tblB.Columns.Add(New DataColumn("Id", GetType(Integer)))
            tblB.Columns.Add(New DataColumn("Name1", GetType(String)))
            tblB.Columns.Add(New DataColumn("Zahl2", GetType(Integer)))
    
            tblB.LoadDataRow(New Object() {1, "top1", 22}, True)
            tblB.LoadDataRow(New Object() {2, "top2", 23}, True)
            tblB.LoadDataRow(New Object() {3, "top3", 24}, True)
            ''************************************************************
     
            Dim query = From A In tblA.AsEnumerable _
                  Join B In tblB.AsEnumerable On _
                  A.Field(Of Integer)("Id") Equals B.Field(Of Integer)("Id") _
                  Select New With { _
                  .Id = A.Field(Of Integer)("Id"), _
                  .Name = A.Field(Of String)("Name"), _
                  .Zahl = A.Field(Of Integer)("Zahl"), _
                  .Name1 = B.Field(Of String)("Name1"), _
                  .Zahl2 = B.Field(Of Integer)("Zahl2")}
    
            '//DataGridView1.DataSource = query.ToList()
    
            '//oder die query (IEnumerable) in einem DataTable konvertieren
            Dim tbl As DataTable = ObtainDataTableFromIEnumerable(query)
            DataGridView1.DataSource = tbl
        End Sub
    
        Private Function ObtainDataTableFromIEnumerable(ien As IEnumerable) As DataTable
            Dim dt As New DataTable()
            For Each obj As Object In ien
                Dim t As Type = obj.[GetType]()
                Dim pis As PropertyInfo() = t.GetProperties()
                If dt.Columns.Count = 0 Then
                    For Each pi As PropertyInfo In pis
                        dt.Columns.Add(pi.Name, pi.PropertyType)
                    Next
                End If
                Dim dr As DataRow = dt.NewRow()
                For Each pi As PropertyInfo In pis
                    Dim value As Object = pi.GetValue(obj, Nothing)
                    dr(pi.Name) = value
                Next
                dt.Rows.Add(dr)
            Next
            Return dt
        End Function

    Grüße,

    Robert


    Robert Breitenhofer, MICROSOFT  Twitter Facebook
    Bitte haben Sie Verständnis dafür, dass im Rahmen dieses Forums, welches auf dem Community-Prinzip „Entwickler helfen Entwickler“ beruht, kein technischer Support geleistet werden kann oder sonst welche garantierten Maßnahmen seitens Microsoft zugesichert werden können.

    Freitag, 24. Februar 2012 10:42
    Moderator
  • Hallo Robert, vielen Dank. Dein erstes Beispiel klappte schon auf Anhieb.
    Gruss

    Freitag, 24. Februar 2012 20:17