[英]How to compare 2 DataTables?
我有2个DataTables可以说:
DataTable OldDataTable = HttpContext.Current.Cache["oldDataTable"];
| ID | Value
| 1 | 0
| 2 | 0
DataTable NewDataTable =/*Get New Record Data*/
| ID | Value
| 1 | 0
| 2 | 1 new Value
| 3 | 0 new Row
我如何比较这两个数据表来做一些工作,如:
警报并更新新值,并将新行更新为oldDataTable
。
然后另一个newDatatable
来了,
DataTable AnotherNewDataTable =/*Get New Record Data*/
| ID | Value
no more record in ID 1
| 2 | 1
| 3 | 0
从oldDataTable
删除该行。
如何保持循环并与新数据表进行比较?
检查DataTable
选择属性
DataRow[] result = NewDataTable.Select("ID <> '" + OldDataTable.Columns['ID'].ToString() + "'"
+ " OR" + " Value <>'" + OldDataTable.Columns['Value'].ToString() + "'");
上面的代码存储DataRow
数组中两个DataTables
之间的不匹配行。 此处<>
表示“不等于”。
(以上示例基于NewDataTable
行多于OldDataTable
。)
您将需要遍历每个表的行,然后遍历该循环内的每一列以比较各个值。
这里有一个代码示例: 比较两个数据表
简而言之,该方法应如下所示:
bool compareTbls(Datatable OldDataTable, Datatable NewDataTable)
{
if(OldDataTable.Rows.Count != NewDataTable.Rows.Count || OldDataTable.Columns.Count != NewDataTable.Columns.Count)
return false;
for(int i = 0; i < OldDataTable.Rows.Count; i++)
{
for(int c = 0; c < OldDataTable.Columns.Count; c++)
{
if(OldDataTable.Rows[i][c] != NewDataTable.Rows.Columns[i][c])
return false;
}
}
return true;
}
尝试以下代码比较两个数据表:
private void button1_Click(object sender, EventArgs e)
{
// Something to do with the Initialization of the FirstDataTable and SecondDataTable
DataTable dt;
dt = getDifferentRecords(FirstDataTable, SecondDataTable);
if (dt.Rows.Count == 0)
MessageBox.Show("Equal");
else
MessageBox.Show("Not Equal");
}
// Compare two DataTables and return a DataTable with DifferentRecords
/// <summary>
/// Compare two DataTables and return a DataTable with DifferentRecords
/// </summary>
/// <param name="FirstDataTable">FirstDataTable</param>
/// <param name="SecondDataTable">SecondDataTable</param>
/// <returns>DifferentRecords</returns>
public DataTable getDifferentRecords(DataTable FirstDataTable, DataTable SecondDataTable)
{
//Create Empty Table
DataTable ResultDataTable = new DataTable("ResultDataTable");
//use a Dataset to make use of a DataRelation object
using (DataSet ds = new DataSet())
{
//Add tables
ds.Tables.AddRange(new DataTable[] { FirstDataTable.Copy(), SecondDataTable.Copy() });
//Get Columns for DataRelation
DataColumn[] firstColumns = new DataColumn[ds.Tables[0].Columns.Count];
for (int i = 0; i < firstColumns.Length; i++)
{
firstColumns[i] = ds.Tables[0].Columns[i];
}
DataColumn[] secondColumns = new DataColumn[ds.Tables[1].Columns.Count];
for (int i = 0; i < secondColumns.Length; i++)
{
secondColumns[i] = ds.Tables[1].Columns[i];
}
//Create DataRelation
DataRelation r1 = new DataRelation(string.Empty, firstColumns, secondColumns, false);
ds.Relations.Add(r1);
DataRelation r2 = new DataRelation(string.Empty, secondColumns, firstColumns, false);
ds.Relations.Add(r2);
//Create columns for return table
for (int i = 0; i < FirstDataTable.Columns.Count; i++)
{
ResultDataTable.Columns.Add(FirstDataTable.Columns[i].ColumnName, FirstDataTable.Columns[i].DataType);
}
//If FirstDataTable Row not in SecondDataTable, Add to ResultDataTable.
ResultDataTable.BeginLoadData();
foreach (DataRow parentrow in ds.Tables[0].Rows)
{
DataRow[] childrows = parentrow.GetChildRows(r1);
if (childrows == null || childrows.Length == 0)
ResultDataTable.LoadDataRow(parentrow.ItemArray, true);
}
//If SecondDataTable Row not in FirstDataTable, Add to ResultDataTable.
foreach (DataRow parentrow in ds.Tables[1].Rows)
{
DataRow[] childrows = parentrow.GetChildRows(r2);
if (childrows == null || childrows.Length == 0)
ResultDataTable.LoadDataRow(parentrow.ItemArray, true);
}
ResultDataTable.EndLoadData();
}
return ResultDataTable;
}
使用linq和2个联接,很容易获得更改(添加,删除或更新)行的确切集合。 这是一个完整的示例:
class Data {
public int ID;
public int value;
}
enum RowState {
Added,
Updated,
Deleted
}
List<Data> OldDataTable = new List<Data> {
new Data { ID = 1, value = 0 },
new Data { ID = 2, value = 0 },
new Data { ID = 3, value = 1 }
};
List<Data> NewDataTable = new List<Data> {
new Data { ID = 1, value = 0 },
new Data { ID = 2, value = 1 },
new Data { ID = 4, value = 2 }
};
void Test() {
//updated and deleted rows
var udRows =
from Old in OldDataTable
join n in NewDataTable on Old.ID equals n.ID
into NewWithNullForDeleted
from subNew in NewWithNullForDeleted.DefaultIfEmpty()
where subNew == null || Old.value != subNew.value
select new {
ID = Old.ID,
OldValue = (int?)Old.value,
NewValue = subNew == null ? (int?)null : (int?)subNew.value,
RowState = subNew == null ? RowState.Deleted : RowState.Updated
};
//added rows
var aRows =
from New in NewDataTable
join o in OldDataTable on New.ID equals o.ID
into OldWithNullForAdded
from subOld in OldWithNullForAdded.DefaultIfEmpty()
where subOld == null
select new {
ID = New.ID,
OldValue = (int?)null,
NewValue = (int?)New.value,
RowState = RowState.Added
};
//merge
var changedRows = udRows.ToList();
changedRows.AddRange(aRows);
//display
foreach (var changedRow in changedRows) {
Console.WriteLine("{0} : '{1}' -> '{2}' ({3})",
changedRow.ID,
changedRow.OldValue, changedRow.NewValue,
changedRow.RowState);
}
}
使用此示例数据运行Test
方法将输出以下内容:
2 : '0' -> '1' (Updated)
3 : '1' -> '' (Deleted)
4 : '' -> '2' (Added)
希望这可以帮助。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.