我有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
我如何比较这两个DataTable来做一些工作:
提醒并更新新值,并将新行更新为oldDataTable
。
然后另一个newDatatable
来了,
DataTable AnotherNewDataTable =/*Get New Record Data*/
| ID | Value
no more record in ID 1
| 2 | 1
| 3 | 0
从oldDataTable
删除该行。
如何保持循环并与新数据表进行比较?
答案 0 :(得分:1)
检查 Select DataTable
DataRow[] result = NewDataTable.Select("ID <> '" + OldDataTable.Columns['ID'].ToString() + "'"
+ " OR" + " Value <>'" + OldDataTable.Columns['Value'].ToString() + "'");
以上代码在DataTables
数组中的两个DataRow
之间存储不匹配的行。这里<>
表示“不等于”。
(以上示例基于NewDataTable
的行数多于OldDataTable
的假设。)
答案 1 :(得分:0)
您需要循环遍历每个表的行,然后遍历该循环中的每个列以比较各个值。
这里有一个代码示例:compare two datatables
简而言之,该方法应该是这样的:
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;
}
答案 2 :(得分:0)
尝试以下代码来比较两个数据表:
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;
}
答案 3 :(得分:0)
使用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)
希望这有帮助。