I am trying to find the correct way to join two datatables, or more, into a single datatable and use it as the datasource for a DataGridView. I have read through all sort of examples and posts, but nothing I've tried seems to be working. I'm sure I'm missing something, but not sure what.
I have three tables: dt_Record (25 columns), dt_ENDP (35 columns) and dt_ITSM (12 columns) and each of these come from different database servers. Because I'm not admin of these servers, I cannot join them in any way. For now I'm just trying to get the first two tables to join so I have a basis of HOW to do it. This joined table/DGV will be used for a report where the user can select which columns they want visible and exported to Excel.
Here is what I have tried per a solution here:
The other form that is opening, and has the DGV, has the following code:Code:Private Sub Open_Report(sender As Object, e As EventArgs) Handles PrintToolStripButton.Click Try ds_Record = New DataSet ds_Record.Tables.Add(dt_Record) ds_Record.Tables.Add(dt_ENDP) Dim dr As DataRelation = New DataRelation("ENDP", ds_Record.Tables(0).Columns("Endpoint_Tag"), ds_Record.Tables(1).Columns("Computer_Name")) ds_Record.Relations.Add(dr) frmIT_Report.ShowDialog() Catch ex As Exception CustExErrorMsg(Me.Name, System.Reflection.MethodBase.GetCurrentMethod().Name, ex.Message) Finally If Not IsNothing(ds_Record) Then ds_Record.Dispose() End Try End Sub
When the form opens, the DGV is only filled with the data from the dt_Records table, and nothing from the second table. OK, fine. Per another solution I found, I added the following, after adding the relation to the dataset, to see if that would bring in the data from the second table:Code:Private Sub frmIT_Report_Load(sender As Object, e As EventArgs) Handles Me.Load Try With dgvResults .RowHeadersWidth = 12 .DataSource = frmIT_Equip.ds_Record.Tables(0) End With txtResults.Text = CStr(dgvResults.Rows.GetRowCount(DataGridViewElementStates.None)) Catch ex As Exception CustExErrorMsg(Name, System.Reflection.MethodBase.GetCurrentMethod().Name, ex.Message) End Try End Sub
Nope, that still only produces the first table. So then I found another solution that required adding a column at the end of the first table:Code:For Each row As DataRow In ds_Record.Tables(0).Rows Row.GetChildRows(dr) Next
But that produces an error of "Cannot find relation 0" So then I went out on a limb with another solution using LINQ to join the tables: (I am not very familiar with LINQ, yet.)Code:ds_Record.Tables(0).Columns.Add("Build_Date", GetType(String), "Parent.Build_Date")
But that produces error "Specified Cast in not allowed" But even if that did work, or the precious code, I don't want to have to cast almost 70 columns in my code - that just seem ludicrous.Code:Dim qry = From t1 In ds_Record.Tables(0).AsEnumerable() Join t2 In ds_Record.Tables(1).AsEnumerable On t1.Item("Endpoint_Tag") Equals t2.Item("Computer_Name") Select New With { Key .A = t1.Field(Of String)("Endpoint_Tag"), .B = t1.Field(Of Integer)("Class_ID"), .C = t2.Field(Of String)("Computer_Name"), .D = t2.Field(Of String)("Build_Date")} Dim dt As New DataTable For Each item In qry.ToList dt.Rows.Add(item.A, item.B, item.C, item.D) Next ds_Record.Tables.Add(dt)
On the surface this seems like it should be easy to solve. So what am I missing?




Reply With Quote
