[英]Compare two datatables and format results
我知道如何在sql中執行此操作,但是對於c#。我無法弄清楚如何對兩個數據表進行比較。
比方說:
第一個數據表:
Name | Balance | Description
Smith | 1200 | Smith owes 600
Jordan| 4000 | Hi Jordan
Brooks| 5000 | I like my cat
Navaro| 6000 | description here
Gates | 9010 | omg
第二個數據表:
Name | Balance | Description
Smith | 1600 | Smith owes 600
Jordan| 4200 | I'M JORDAN
Clay | 9000 | Test description
Brooks| 5000 | I like my cat
我想將比較結果轉儲到簡單的html表中。
太...結果應該是這樣的:
基本上我需要的是:
顯示不同的列並顯示數據
如果所有列都相同,則不顯示記錄
顯示僅存在於第一個數據表中的記錄(僅名稱)
顯示僅存在於第二個數據表中的記錄(僅名稱)
在sql中,您可以執行諸如merge的操作,然后進行透視。
但是在C#中,我的發現是:我可以使用except或intersect,但是它返回一個可引用的數據。 除\\ intersection函數外,是否有任何格式設置選項?
我正在尋找有關如何以最佳方式實現此目標的建議。 (每個數據表中大約有100列)。 所有名稱都應進行比較。
這是您需要在.cs文件中包含的代碼...
(我只創建了這兩個空類,以避免在代碼中包含Dictionary<object, Dictionary<string, Tuple<object, object>>>
但是如果願意,可以替換為該類)
protected class Differences : Dictionary<object, RowDifferences>
{
}
protected class RowDifferences : Dictionary<string, Tuple<object, object>>
{
}
protected Differences GetDifferences(DataTable table1,
DataTable table2,
out IEnumerable<object> onlyIn1,
out IEnumerable<object> onlyIn2)
{
var arr1 = new DataRow[table1.Rows.Count];
var arr2 = new DataRow[table2.Rows.Count];
table1.Rows.CopyTo(arr1, 0);
table2.Rows.CopyTo(arr2, 0);
onlyIn1 = arr1.Where(x1 => arr2.All(x2 => x1[0] != x2[0])).Select(dr => dr[0]);
onlyIn2 = arr2.Where(x1 => arr1.All(x2 => x1[0] != x2[0])).Select(dr => dr[0]);
var differences = new Differences();
foreach (var x1 in arr1)
{
foreach (var x2 in arr2)
{
if (x1[0] == x2[0])
{
var rowDifferences = new RowDifferences();
for (var i = 1; i < x1.ItemArray.Length; i++)
{
if (x1.ItemArray[i] != x2.ItemArray[i])
{
rowDifferences.Add(table1.Columns[i].ColumnName,
new Tuple<object, object>(x1.ItemArray[i], x2.ItemArray[i]));
}
}
differences.Add(x1[0], rowDifferences);
}
}
}
return differences;
}
protected void GenerateTables(out DataTable table1, out DataTable table2)
{
table1 = new DataTable();
table2 = new DataTable();
table1.Columns.Add("Name");
table1.Columns.Add("Balance");
table1.Columns.Add("Description");
table2.Columns.Add("Name");
table2.Columns.Add("Balance");
table2.Columns.Add("Description");
table1.Rows.Add("Smith", 1200, "Smith owes 600");
table1.Rows.Add("Jordan", 4000, "Hi Jordan");
table1.Rows.Add("Brooks", 5000, "I like my cat");
table1.Rows.Add("Navaro", 6000, "description here");
table1.Rows.Add("Gates", 9010, "omg");
table2.Rows.Add("Smith", 1600, "Smith owes 600");
table2.Rows.Add("Jordan", 4200, "I'M JORDAN");
table2.Rows.Add("Clay", 9000, "Test description");
table2.Rows.Add("Brooks", 5000, "I like my cat");
}
這是一個如何在.aspx文件中從中構建表的示例:
<%
DataTable table1, table2;
GenerateTables(out table1, out table2);
IEnumerable<object> onlyIn1, onlyIn2;
var differences = GetDifferences(table1, table2, out onlyIn1, out onlyIn2);
%>
<table>
<thead>
<tr>
<th>Name</th>
<th>RecordName</th>
<th>1st Datatable</th>
<th>2nd Datatable</th>
</tr>
</thead>
<tbody>
<%
foreach (var difference in differences)
{
%>
<tr>
<td><%=difference.Key%></td>
</tr>
<%
foreach (var rowDifferences in difference.Value)
{
%>
<tr>
<td></td>
<td><%=rowDifferences.Key%></td>
<td><%=rowDifferences.Value.Item1%></td>
<td><%=rowDifferences.Value.Item2%></td>
</tr>
<%
}
}
%>
<tr>
<td>Only 1st datatable</td>
</tr>
<%
foreach (var name in onlyIn1)
{
%>
<tr>
<td><%=name%></td>
</tr>
<%
}
%>
<tr>
<td>Only 2st datatable</td>
</tr>
<%
foreach (var name in onlyIn2)
{
%>
<tr>
<td><%=name%></td>
</tr>
<%
}
%>
</tbody>
</table>
從現在開始,按您希望的方式設計桌子並不難。
因此,剩下的主要事情是將GenerateTables
更改為某些查詢邏輯,甚至將其內GetDifferences
在GetDifferences
。
查找算法可能可以完善。 在最壞的情況下,當前值為O(m * n * k),m和n分別是table1和table2中的行數,k是列數。 我已經想出了很多方法可以改善它,但我將留給您。 這應該使您入門又好又好。
只需注意,該算法假定兩個表之間的列相等。
讓我知道解決方案是否還不清楚,祝您好運!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.