如何比较2个DataTables?

时间:2012-11-30 11:08:16

标签: c#

我有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删除该行。

如何保持循环并与新数据表进行比较?

4 个答案:

答案 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)

希望这有帮助。