vb.net - 如何在 VB.NET 中内连接两个已填充的 DataTable

标签 vb.net datatable merge inner-join

我将 Der Golem 的答案标记为正确,因为它是我所说的具体问题的正确答案。

不幸的是,我未能检测到 datatable2 中的记录不是唯一的这一事实,这显然与在两个表上执行“内连接”以获得我想要的结果不太相符。

如果是的话,设置 DataRelation 就可以了。


我对 VB.NET 还很陌生,所以请耐心等待。

  • 我有两个数据表,每个表都由不同的数据库服务器填充。
  • 它们都有三列(为了便于测试,最终程序将有 50 多个列)。
  • 它们都有一个公共(public)数据列,我想通过(“OrderNum”)进行内连接。

这里有一个问题,但“答案”对我不起作用,它下面的 LINQ 选项也不起作用: Merging 2 data tables in vb.net

这是我的示例代码:

DB1 = New DatabaseConnectionSQL1
DB1.OpenConn()
DB2 = New DB_DatabaseConnectionSQL2
DB2.OpenConn()

Dim dtA As DataTable = New DataTable("DataTable1")
Dim dtB As DataTable = New DataTable("DataTable2")
Dim dtCombined As DataTable = New DataTable("CombinedDataTable")

dtA.Columns.Add("Order", System.Type.GetType("System.String"))
dtA.Columns.Add("Account_Number", System.Type.GetType("System.String"))
dtA.Columns.Add("Account_Name", System.Type.GetType("System.String"))

'"Order" = "Head_Order_Number"

dtB.Columns.Add("Head_Order_Number", System.Type.GetType("System.String"))
dtB.Columns.Add("Line_Number", System.Type.GetType("System.Int32"))
dtB.Columns.Add("Model", System.Type.GetType("System.String"))

dtA = DB1.GetDataTable(sQuery1)
dtB = DB2.GetDataTable(sQuery2)

'This doesn't work as it just appends the table
'dtA.Merge(dtB, True)
'I tried creating a DataSet and setting a Relation, but that kept failing
'I've tried at least 10 different things here. I'm at my wit's end.

dgvDataGrid.DataSource = dtCombined 
dgvDataGrid.Refresh()

DB1.CloseConn()
DB2.CloseConn()

我注意到其他地方的人建议使用 Linq。尽管我不熟悉,但我尽力了,但还是失败。

表 A (dtA):

Order | Account_Number | Account_Name
10000 | 10000000000001 | BlahA
20000 | 10000000000002 | BlahB
30000 | 10000000000003 | BlahC

表 B (dtB):

Head_Order_Number| Line_Number | Model
10000            | 00000000034 | MD35Z
15000            | 00000000530 | MX25A
25000            | 00000024535 | P231Y
20000            | 00000027735 | A511L
30000            | 00000000910 | M232C

我想将两者结合起来(dtCombined):

Order | Account_Number | Account_Name | Line_Number | Model
10000 | 10000000000001 | BlahA        | 00000000034 | MD35Z
20000 | 10000000000002 | BlahB        | 00000027735 | A511L
30000 | 10000000000003 | BlahC        | 00000000910 | M232C

任何帮助将不胜感激。


我之前尝试添加 DataRelation 并不断收到错误,但我没有正确设置某些内容。现在我解决了这个问题,我又收到了另一个错误:

“System.ArgumentException:无法启用此约束,因为并非所有值都有相应的父值。”

dt1 = New DataTable("DataTable1")
dt1.Columns.Add("order_number", System.Type.GetType("System.String"))
dt1.Columns.Add("account_name", System.Type.GetType("System.String"))

dt2 = New DataTable("DataTable2")
dt2.Columns.Add("head_order_number", System.Type.GetType("System.String"))
dt2.Columns.Add("model", System.Type.GetType("System.String"))

Conn1.ConnectionString = sConnString1
Dim da1 As SqlDataAdapter = New SqlDataAdapter(sQuery1, Conn1)
Conn1.Open()

Conn2.ConnectionString = sConnString2
Dim da2 As SqlDataAdapter = New SqlDataAdapter(sQuery2, Conn2)
Conn2.Open()

ds = New DataSet
da1.Fill(ds, "DataTable1")
da2.Fill(ds, "DataTable2")

Dim dr As DataRelation = New DataRelation("Combined", _
    ds.Tables("DataTable1").Columns("OrderNo"), _
    ds.Tables("DataTable2").Columns("OrderNo"))
ds.Relations.Add(dr)

dgvDataGrid.DataSource = ds
dgvDataGrid.Refresh()

Conn1.Close()
Conn2.Close()

这个错误似乎是有道理的,因为 DataTable1 总共有 1950 行,而 DataTable2 总共有 4000 多行,但这不是 DataRelation 的重点吗?它有效地内部联接两个表,因此最终结果应该是 1950 行?

最佳答案

您要执行的查询如下所示:

Dim sql As String = "SELECT dta.*, dtB.* FROM dtA INNER JOIN dtB ON dtA.Order = dtB.Order"

请注意,Order = 25000 的记录不是 INNER JOIN 的一部分

[编辑]

根据您的评论,我发现您缺乏一些知识......

所以 - 假设您已经准备好数据库连接(conn):

Dim cmd As OleDbCommand = New OleDbCommand(sql, conn)
Dim da As OleDbDataAdapter = New OleDbDataAdapter
da.SelectCommand = cmd
conn.Open()
Dim ds As DataSet = New DataSet
da.Fill(ds, "Result")
conn.Close()

dgvDataGrid.datasource = ds
ds.DataBind()

我假设一个 OleDb 连接 - 但 SQL 连接实际上是相同的(用 Sql 替换 OleDb)

[编辑2]你决定让我出汗!

最后,针对您的具体问题提供了解决方案:

如下所示:http://msdn.microsoft.com/en-us/library/cc188919.aspx

DataRelation 对象就是您所需要的。

创建 DataRelation 对象

' Create the DataRelation and
' relate the customers to their orders
DataRelation oDr_Customer2Order = new DataRelation("Customer2Order",
    oDs.Tables["Customer"].Columns["CustomerID"],
    oDs.Tables["Order"].Columns["CustomerID"]);
oDs.Relations.Add(oDr_Customer2Order);

通过创建 DataRelation 对象,然后将它们添加到 DataSet 的关系集合中,三个 DataTable 对象的行集通过定义的字段相互关联。与大多数 ADO.NET 对象一样,DataRelation 对象有几个不同的构造函数。我使用了接受关系名称、父表列和子表列的构造函数。如果有多个定义关系的列,我可以传入父表列的数组和子表列的数组。另一种选择是使用与图 3 中相同的前三个参数,然后传入第四个参数来表示是否应自动创建约束(传入 bool 值)。但稍后会详细讨论约束。 一旦 DataSet 填充了三个行集并且建立了链接 DataTable 对象的关系,通过设置 DataSource 属性,可以轻松地将 DataSet 显示在 Web 窗体上的 DataGrid 中,如下所示:

dataGrid1.DataSource = oDs;

DataGrid 足够聪明,可以发现需要显示多个 DataTable 对象,并且它应该允许按照 DataRelation 对象规定的顺序导航行集。

关于vb.net - 如何在 VB.NET 中内连接两个已填充的 DataTable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23660112/

相关文章:

vb.net - 在文本框中输入时出现 AccessViolationException

java - 输入字段更改后的 Wicket 数据表过滤

Python 无法识别重复项

arrays - 将两个文件中的对象数组与特定键 1.4 下的 jq 结合起来

vb.net - 在vb.net中构建多维数组

从 vb 应用程序插入的 mysql (phpmyadmin) 行没有得到更新

javascript - ASP.Net webservices 中的 JSON 数组类型解析

c# - 将数据库查询数据显示为表格

c# - C#中如何将DataTable转换为对象类型List

mysql - 我需要合并具有 1 个相似列和第二个唯一列的两个列表