web-dev-qa-db-ja.com

2つのDataTableを比較し、2番目のテーブルに存在しない行を選択します

2つのDataTableがあり、2番目には存在しない最初の行から行を選択したい

例えば:

表A 
 id列
 1 data1 
 2 data2 
 3 data3 
 4 data4 
 
表B 
 id列
 1 data10 
 3 data30 

結果を次のようにします。

表C 
 id列
 2 data2 
 4 data4 
16
Catalin

Linqを使用できます。特にEnumerable.Exceptは、TableBにないTableAのidを見つけるのに役立ちます。

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();

Whereを使用することもできますが、効率は低下します。

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

私は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();

        }
    }
}

詳細については、 http://microsoftdotnetsolutions.blogspot.in/2012/12/compare-two-datatables.html

4
sai

LinqEnumerable.Exceptメソッド関数を使用して、2つのDataTableの差分を取得できます。ここでは、firstDtとsecondDtを使用します。

 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
            }
        }

Enumerable.Exceptメソッドの詳細については、 http://msdn.Microsoft.com/en-us/library/system.linq.enumerable.except(v = vs.110).aspx にアクセスしてください。

そしてその完了!!!!ハッピーコーディング.........

0
Abdul