wake-up-neo.net

So vergleichen Sie 2 Datentabellen

Ich habe 2 Datatables und möchte nur wissen, ob sie gleich sind oder nicht. Mit "gleich" meine ich, dass sie genau dieselbe Anzahl von Zeilen mit genau denselben Daten in jeder Spalte haben oder nicht. Ich würde gerne eine Methode schreiben (finden), die beide Tabellen akzeptiert und einen Booleschen Wert zurückgibt. 

Wie kann ich 2 Datentabellen auf diese Weise vergleichen? Beide haben identische Schemata.

20
MAW74656

Sie müssten die Zeilen jeder Tabelle durchlaufen und dann jede Spalte innerhalb der Schleife durchlaufen, um die einzelnen Werte zu vergleichen.

Es gibt ein Codebeispiel hier: http://canlu.blogspot.com/2009/05/wie-nach-compare-two-datatables-in-adonet.html

7
David
 public static bool AreTablesTheSame( DataTable tbl1, DataTable tbl2)
 {
    if (tbl1.Rows.Count != tbl2.Rows.Count || tbl1.Columns.Count != tbl2.Columns.Count)
                return false;


    for ( int i = 0; i < tbl1.Rows.Count; i++)
    {
        for ( int c = 0; c < tbl1.Columns.Count; c++)
        {
            if (!Equals(tbl1.Rows[i][c] ,tbl2.Rows[i][c]))
                        return false;
        }
     }
     return true;
  }
20
Nick Rolando

Wenn Sie eine DataTable als Funktion zurückgeben, können Sie:

DataTable dataTable1; // Load with data
DataTable dataTable2; // Load with data (same schema)

    var differences =
        dataTable1.AsEnumerable().Except(dataTable2.AsEnumerable(),
                                            DataRowComparer.Default);

    return differences.Any() ? differences.CopyToDataTable() : new DataTable();
9
samneric

Das OP, MAW74656 , hatte diese Antwort ursprünglich im Antworttext als Antwort auf die akzeptierte Antwort veröffentlicht, wie in dieser Kommentar erläutert

Ich habe dies verwendet und eine öffentliche Methode geschrieben, um den Code aufzurufen und den Boolean zurückzugeben.

Die Antwort des OP:

Code verwendet:

public bool tablesAreTheSame(DataTable table1, DataTable table2)
{
    DataTable dt;
    dt = getDifferentRecords(table1, table2);

    if (dt.Rows.Count == 0)
        return true;
    else
        return false;
}

//Found at http://canlu.blogspot.com/2009/05/how-to-compare-two-datatables-in-adonet.html
private 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;
}
5
JDB

Versuchen Sie, linq für Dataset zu verwenden 

(from b in table1.AsEnumerable()  
    select new { id = b.Field<int>("id")}).Except(
         from a in table2.AsEnumerable() 
             select new {id = a.Field<int>("id")})

Überprüfen Sie diesen Artikel: Vergleichen von DataSets mit LINQ

3
Pranay Rana

Ich habe die Lösung für den Vergleich von 2 Datentabellen erhalten

http://microsoftdotnetsolutions.blogspot.in/2012/12/compare-two-datatables.html

2
sai

Wenn sich die Tabellen in einer Datenbank befinden, können Sie einen vollständigen äußeren Join erstellen, um die Unterschiede zu ermitteln. Beispiel:

select t1.Field1, t1.Field2, t2.Field1, t2.Field2
from Table1 t1
full outer join Table2 t2 on t1.Field1 = t2.Field1 and t1.Field2 = t2.Field2
where t1.Field1 is null or t2.Field2 is null

Alle Datensätze, die identisch sind, werden herausgefiltert. In den ersten beiden oder den letzten beiden Feldern befinden sich Daten, je nachdem aus welcher Tabelle der Datensatz stammt.

1
Guffa
    /// <summary>
    /// https://stackoverflow.com/a/45620698/2390270
    /// Compare a source and target datatables and return the row that are the same, different, added, and removed
    /// </summary>
    /// <param name="dtOld">DataTable to compare</param>
    /// <param name="dtNew">DataTable to compare to dtOld</param>
    /// <param name="dtSame">DataTable that would give you the common rows in both</param>
    /// <param name="dtDifferences">DataTable that would give you the difference</param>
    /// <param name="dtAdded">DataTable that would give you the rows added going from dtOld to dtNew</param>
    /// <param name="dtRemoved">DataTable that would give you the rows removed going from dtOld to dtNew</param>
    public static void GetTableDiff(DataTable dtOld, DataTable dtNew, ref DataTable dtSame, ref DataTable dtDifferences, ref DataTable dtAdded, ref DataTable dtRemoved)
    {
        try
        {
            dtAdded = dtOld.Clone();
            dtAdded.Clear();
            dtRemoved = dtOld.Clone();
            dtRemoved.Clear();
            dtSame = dtOld.Clone();
            dtSame.Clear();
            if (dtNew.Rows.Count > 0) dtDifferences.Merge(dtNew.AsEnumerable().Except(dtOld.AsEnumerable(), DataRowComparer.Default).CopyToDataTable<DataRow>());
            if (dtOld.Rows.Count > 0) dtDifferences.Merge(dtOld.AsEnumerable().Except(dtNew.AsEnumerable(), DataRowComparer.Default).CopyToDataTable<DataRow>());
            if (dtOld.Rows.Count > 0 && dtNew.Rows.Count > 0) dtSame = dtOld.AsEnumerable().Intersect(dtNew.AsEnumerable(), DataRowComparer.Default).CopyToDataTable<DataRow>();
            foreach (DataRow row in dtDifferences.Rows)
            {
                if (dtOld.AsEnumerable().Any(r => Enumerable.SequenceEqual(r.ItemArray, row.ItemArray))
                    && !dtNew.AsEnumerable().Any(r => Enumerable.SequenceEqual(r.ItemArray, row.ItemArray)))
                {
                    dtRemoved.Rows.Add(row.ItemArray);
                }
                else if (dtNew.AsEnumerable().Any(r => Enumerable.SequenceEqual(r.ItemArray, row.ItemArray))
                    && !dtOld.AsEnumerable().Any(r => Enumerable.SequenceEqual(r.ItemArray, row.ItemArray)))
                {
                    dtAdded.Rows.Add(row.ItemArray);
                }
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine(ex.ToString());
        }
    }
1
Audreth

Es gibt nichts, was dies für Sie tun wird. Die einzige Möglichkeit, dies zu erreichen, besteht darin, alle Zeilen/Spalten zu iterieren und sie miteinander zu vergleichen.

0
CodingGorilla

oder ich habe den Array-Vergleich nicht implementiert, so werden Sie auch etwas Spaß haben :)

public bool CompareTables(DataTable a, DataTable b)
{
    if(a.Rows.Count != b.Rows.Count)
    {
        // different size means different tables
        return false;
    }

    for(int rowIndex=0; rowIndex<a.Rows.Count; ++rowIndex)
    {
        if(!arraysHaveSameContent(a.Rows[rowIndex].ItemArray, b.Rows[rowIndex].ItemArray,))
        {
            return false;
        }
    }

    // Tables have same data
    return true;
}

private bool arraysHaveSameContent(object[] a, object[] b)
{
    // Here your super cool method to compare the two arrays with LINQ,
    // or if you are a loser do it with a for loop :D
}
0
Davide Piras

Wenn Sie überhaupt eine DataTable verwenden, können Sie, anstatt zwei "DataTables" zu vergleichen, einfach die DataTable, die Änderungen aufweist, mit den ursprünglichen Daten vergleichen, als sie geladen wurden. AKA DataTable.GetChanges-Methode (DataRowState)

0
Coops