我认为Der Golem的答案是正确的,因为它是我说过的具体问题的正确答案。
不幸的是,我没有发现datatable2中的记录并不是唯一的事实,这显然不能很好地执行"内部连接"在两张桌子上我想要的结果。
如果是,则设置DataRelation将起作用。
我还是VB.NET的新手,所以请耐心等待。
这里有一个问题,但是"答案"对我不起作用,也不对它下面的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行?
答案 0 :(得分:4)
您要执行的查询如下所示:
Dim sql As String = "SELECT dta.*, dtB.* FROM dtA INNER JOIN dtB ON dtA.Order = dtB.Order"
请注意, <强> [编辑] 强> 根据你的评论,我发现你缺乏一些知识...... 所以 - 假设你已经准备好了你的数据库连接(conn): 我假设是OleDb连接 - 但是SQL连接真的是一样的(用Sql替换OleDb) [编辑2] 你决定让我出汗! 最后,针对您的具体问题提供了解决方案: 如下所示:http://msdn.microsoft.com/en-us/library/cc188919.aspx DataRelation对象就是您所需要的。 创建DataRelation对象 通过创建DataRelation对象然后将它们添加到DataSet的Relations集合,三个DataTable对象的行集通过定义的字段相互关联。与大多数ADO.NET对象一样,DataRelation对象有几个不同的构造函数。我使用了接受关系名称,父表列和子表列的构造函数。如果有多个列定义了关系,我可以传入父表的列数组和子表列的数组。另一种选择是使用我在图3中使用的相同的前三个参数,然后传入第四个参数来表示是否应该自动创建约束(传入布尔值)。但更多的是关于时刻的限制。
一旦DataSet填充了三个行集并建立了连接DataTable对象的关系,DataSet就可以通过设置DataSource属性轻松地显示在Web窗体的DataGrid中: DataGrid足够聪明,可以确定需要显示多个DataTable对象,并且应该允许按照DataRelation对象规定的顺序导航行集。Order = 25000
的记录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()
' 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);
dataGrid1.DataSource = oDs;