我有两个数据表。我想合并它们,并希望从两个数据表中只获取不匹配的行。有人可以帮忙吗?
目前我正在使用以下代码,但它什么都没有返回:
Actual_Table = myDataSet_Actual.Tables("Actuals")
Planned_Table = myDataset_Planned.Tables("Planned")
Planned_Table.AcceptChanges()
Planned_Table.Merge(Actual_Table, False)
change = Planned_Table.GetChanges(DataRowState.Added)
DGV1.DataSource = change ' DGV1= Data grid view
答案 0 :(得分:0)
我希望这可以帮到你:http://www.dotnetperls.com/datatable-compare-rows
在示例中,它将比较结果写入控制台,但我猜你可以做出魔术;)
祝你好运! 编辑:实际上,如果您的DataTable
具有相同的行数并且您要将这些行进行一对一比较,那么您应该更改一个For Each
语句For
声明。类似的东西:
For i As Integer = 0 To RowNo - 1
'compare datatable1_row(i) with datatable2_row(i) and do the magic
Next
答案 1 :(得分:0)
您可以使用以下代码执行此操作,但请继续阅读以获取更多详细信息:
change = Planned_Table.AsEnumerable _
.Except(Actual_Table.AsEnumerable, DataRowComparer.Default) _
.CopyToDataTable
正如此question中指出的那样,DataTable.Merge
不会更改行状态,因此查找DataRowState.Added
行始终为空。
此外,Merge
将第二个表中的每一行添加到第一个表中,因此即使RowState 具有,第二个表中的所有也会出现改变。
最后,假设我们只将第二个数据表中的唯一值添加到第一个数据表中,我们只返回第二个集合中的元素,而不是第一个集合中的元素。也许这就是你想要的,但是如果你真的想要其中任何一个,我会描述这两个选项。
如其他SO问题here和here中所示,我们可以使用LINQ Set Operations
中的任何一个找到正确的条目集:
您可以在MSDN中进一步探索这些内容,但正如this中提到的那样,Union
和Concat
中的DataRow
和IEqualityComparer
都可以将枚举附加到另一个上,但是Union将删除重复项(在检查DataRowComparer.Default
的相等性时,您必须传入重载的DataTableExtensions
= Dim dt, dataTable1, dataTable2 As New DataTable
With dt.Columns
.Add("ID", GetType(Integer))
.Add("Name", GetType(String))
End With
dataTable1 = dt.Clone
dataTable2 = dt.Clone
With dataTable1.Rows
.Add(1, "Tod")
.Add(2, "Jim")
End With
With dataTable2.Rows
.Add(2, "Jim")
.Add(3, "Han")
End With
)
另外,我们要枚举DataTable,为此,我们需要从Right Outer Join
命名空间调用AsEnumerable
方法。
我们正在查看相同的代码,这里有一些我们可以执行设置操作的基本DataTable
Full Outer Join
因此,如果您只希望第二个表中的新项目没有出现在第一个表格中,那么您需要一个Inner Join
:
如果您希望两组之间的所有数据不同,则需要Except
排除Datatable
您可以在此Jeff Atwood post中详细了解不同的集合以及创建它们的联接。
如果你想要第一个选项,你可以通过在第二个Dim just2 As DataTable
just2 = dataTable2.AsEnumerable _
.Except(dataTable1.AsEnumerable, DataRowComparer.Default) _
.CopyToDataTable()
上调用| ID | Name |
| 3 | Han |
并传入第一个
DataRowComparer
输出将是:
Union
如果您想要每组中的唯一值,则必须调用distinct两次,然后将这两个值连接起来。我们不需要将Dim just1 As IEnumerable(Of DataRow)
Dim just2 As IEnumerable(Of DataRow)
Dim union As DataTable
'get rows that are only in table1
just1 = dataTable1.AsEnumerable.Except(dataTable2.AsEnumerable, DataRowComparer.Default)
'get rows that are only in table2
just2 = dataTable2.AsEnumerable.Except(dataTable1.AsEnumerable, DataRowComparer.Default)
'get all unique rows
union = just1.Union(just2).CopyToDataTable
传递给CopyToDataTable
方法,因为我们保证两个表中没有重复项
IEnumerable(Of DataRow)
由于我们不需要单独使用唯一元素集,因此无需致电AsEnumerable
,因此我们可以使用| ID | Name |
| 1 | Tod |
| 3 | Han |
联合的输出将是:
{{1}}