web-dev-qa-db-fra.com

Comparez deux DataTables et sélectionnez les lignes qui ne sont pas présentes dans le deuxième tableau

J'ai deux DataTables et je veux sélectionner les lignes de la première qui ne sont pas présentes dans la seconde

Par exemple:

 Tableau A 
 Colonne id 
 1 données1 
 2 données2 
 3 données3 
 4 données4 
 
 Tableau B 
 Colonne id 
 1 données10 
 3 données30 

Je veux que le résultat soit:

 Tableau C 
 Colonne id 
 2 données2 
 4 données4 
16
Catalin

Vous pouvez utiliser Linq, en particulier Enumerable.Except aide à trouver des identifiants dans TableA qui ne sont pas dans TableB:

var idsNotInB = TableA.AsEnumerable().Select(r => r.Field<int>("id"))
        .Except(TableB.AsEnumerable().Select(r => r.Field<int>("id")));
DataTable TableC = (from row in TableA.AsEnumerable()
                   join id in idsNotInB 
                   on row.Field<int>("id") equals id
                   select row).CopyToDataTable();

Vous pouvez également utiliser Where mais ce sera moins efficace:

DataTable TableC = TableA.AsEnumerable()
    .Where(ra =>  !TableB.AsEnumerable()
                        .Any(rb => rb.Field<int>("id") == ra.Field<int>("id")))
    .CopyToDataTable();
18
Tim Schmelter

J'ai obtenu une solution qui fonctionne sans LINQ:

public DataTable CompareDataTables(DataTable first, DataTable second)
{
    first.TableName = "FirstTable";
    second.TableName = "SecondTable";

    //Create Empty Table
    DataTable table = new DataTable("Difference");

    try
    {
        //Must use a Dataset to make use of a DataRelation object
        using (DataSet ds = new DataSet())
        {
            //Add tables
            ds.Tables.AddRange(new DataTable[] { first.Copy(), second.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 r = new DataRelation(string.Empty, firstcolumns, secondcolumns, false);

            ds.Relations.Add(r);

            //Create columns for return table
            for (int i = 0; i < first.Columns.Count; i++)
            {
                table.Columns.Add(first.Columns[i].ColumnName, first.Columns[i].DataType);
            }

            //If First Row not in Second, Add to return table.
            table.BeginLoadData();

            foreach (DataRow parentrow in ds.Tables[0].Rows)
            {
                DataRow[] childrows = parentrow.GetChildRows(r);
                if (childrows == null || childrows.Length == 0)
                    table.LoadDataRow(parentrow.ItemArray, true);
            }

            table.EndLoadData();

        }
    }
}

Pour en savoir plus, visitez http://microsoftdotnetsolutions.blogspot.in/2012/12/compare-two-datatables.html

4
sai

Vous pouvez utiliser Linq Enumerable.Except Fonction de méthode pour obtenir la différence entre deux DataTable Ici, j'utilise firstDt et secondDt, rappelez-vous que les deux Dt ont la même structure.

 var EntriesNotInB = firstDt.AsEnumerable().Select(r => r.Field<string>("abc")).Except(secondDt.AsEnumerable().Select(r => r.Field<string>("abc")));

        if (EntriesNotInB.Count() > 0)
        {
            DataTable dt = (from row in firstDt.AsEnumerable()join id in EntriesNotInB  on row.Field<string>("abc") equals id select row).CopyToDataTable();
            foreach (DataRow row in dt.Rows)
            {
              /////Place your code to manipulate on datatable Rows
            }
        }

Pour en savoir plus sur la méthode Enumerable.Except, accédez à http://msdn.Microsoft.com/en-us/library/system.linq.enumerable.except (v = vs.110) .aspx

et c'est fait !!!! Bon codage .........

0
Abdul