【发布时间】:2021-05-09 20:14:13
【问题描述】:
我正在尝试找到将两个或多个数据表连接到单个数据表中并将其用作 DataGridView 的数据源的正确方法。我已经阅读了各种示例和帖子,但我尝试过的任何方法似乎都没有奏效。我确定我错过了什么,但不确定是什么。
我有三个表:dt_Record(25 列)、dt_ENDP(35 列)和 dt_ITSM(12 列),每一个都来自不同的数据库服务器。因为我不是这些服务器的管理员,所以我不能以任何方式加入它们。现在我只是想让前两个表加入,所以我有一个如何做的基础。此连接表/DGV 将用于报告,用户可以在该报告中选择他们希望哪些列可见并导出到 Excel。
这是我根据solution here 尝试过的:
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
另一个正在打开的具有 DGV 的表单具有以下代码:
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
当表单打开时,DGV 仅填充 dt_Records 表中的数据,而第二个表中没有任何内容。好的。根据我找到的另一个解决方案,在将关系添加到数据集之后,我添加了以下内容,以查看是否会从第二个表中引入数据:
For Each row As DataRow In ds_Record.Tables(0).Rows
Row.GetChildRows(dr)
Next
不,这仍然只生成第一个表。然后我找到了另一个解决方案,需要在第一个表的末尾添加一列:
ds_Record.Tables(0).Columns.Add("Build_Date", GetType(String), "Parent.Build_Date")
但这会产生“找不到关系 0”的错误,所以我用另一种解决方案使用 LINQ 加入表格:(我对 LINQ 还不是很熟悉。)
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)
但这会产生错误“Specified Cast in not allowed”但即使这确实有效,或者宝贵的代码,我也不想在我的代码中强制转换近 70 列 - 这看起来很可笑。
从表面上看,这似乎应该很容易解决。那我错过了什么?
【问题讨论】:
-
主要是使用
DataTables而不是匿名或定义的类不能与现代 .Net 类(如 DGV)完全互操作。 OTOH,类也不容易合并许多属性(列)。此外,无论如何,70 列在数据网格中的价值值得怀疑。 -
@NetMage 我不同意 70 列对于 DGV 来说是荒谬的。但是,用户希望在采取该操作之前查看他们将要导出的数据。而且由于“组织”在 SQL 数据管理方面做得很糟糕,因此在各种表中的服务器上都有数据。我只是想把它拼凑起来供我自己使用。