web-dev-qa-db-ja.com

2つのDataTableの違いを取得する方法

これらの2つのデータテーブルがあり、それらの違いを取得したいと考えています。次に例を示します。

Table1
-------------------------
ID  |   Name 
--------------------------
 1  |  A
 2  |  B
 3  |  C
--------------------------

Table2
-------------------------
ID  |   Name 
--------------------------
 1  |  A
 2  |  B
--------------------------

テーブル1にあり、テーブル2にないデータとして結果が欲しいだけです(table1-table2)

ResultTable
-------------------------
ID  |   Name 
--------------------------
 3  |  C
--------------------------

Linqを介してこれら2つの類似したソリューションを使用しようとしましたが、常にtable1を返し、table1-table2は返しません。ここに最初の解決策があります:

DataTable table1= ds.Tables["table1"];
DataTable table2= ds.Tables["table2"];
var diff= table1.AsEnumerable().Except(table2.AsEnumerable(),DataRowComparer.Default);

2番目の解決策:

var dtOne = table1.AsEnumerable();
var dtTwo = table2.AsEnumerable();
var difference = dtOne.Except(dtTwo);

では、間違いはどこにあるのでしょうか?たくさんのご回答ありがとうございました。 :)

21
user2095405

次のコードを試すことができます...

table1.AsEnumerable().Where(
    r =>!table2.AsEnumerable().Select(x=>x["ID"]).ToList().Contains(r["ID"])).ToList();
7
Amol Kolekar

私はこれを経験し、私の発見を共有したいと思いました。私のアプリケーションでは、データ同期メカニズムですが、これが元の質問にどのように適用されるかを理解できると思います。

私の場合、私のlastデータのアップロードを表すDataTableがあり、将来的にはcurrentデータの状態を取得する必要があり、違いのみをアップロードします。

//  get the Current state of the data
DataTable dtCurrent = GetCurrentData();

//  get the Last uploaded data
DataTable dtLast = GetLastUploadData();
dtLast.AcceptChanges();

//  the table meant to hold only the differences
DataTable dtChanges = null;

//  merge the Current DataTable into the Last DataTable, 
//  with preserve changes set to TRUE
dtLast.Merge(dtCurrent, true);

//  invoke GetChanges() with DataRowState.Unchanged
//    !! this is the key !!
//    the rows with RowState == DataRowState.Unchanged 
//    are the differences between the 2 tables
dtChanges = dtLast.GetChanges(DataRowState.Unchanged);

これがお役に立てば幸いです。私はこれと数時間戦い、interwebzで多くの偽りのリードを見つけ、いくつかの異なる方法をマージした後でRowStatesを比較しました

5
Kevin.Hardy

DataTableではなく、列レベルでそれを実行しようとします。

_IEnumerable<int> id_table1 = table1.AsEnumerable().Select(val=> (int)val["ID"]);
IEnumerable<int> id_table2  = table2.AsEnumerable().Select(val=> (int)val["ID"]);
IEnumerable<int> id_notinTable1= id_table2.Except(id_table1);
_

.Select()を答えに追加するだけ...

1
SKJ

以下をお試しください。これは基本的なものです。 2つのセットをマージして、違いを取得します。セットが正しく整列しない場合、これは機能しません。同じことをテストしよう

DataSet firstDsData = new DataSet();
DataSet secondDsData = new DataSet();
DataSet finalDsData = new DataSet();
DataSet DifferenceDataSet = new DataSet();
finalDsData.Merge(firstDsData);
finalDsData.AcceptChanges();
finalDsData.Merge(secondDsData);
DifferenceDataSet = finalDsData.GetChanges();
1
user6826239

これを試して

DataTable dtmismatch = Table1.AsEnumerable().Except(Table2.AsEnumerable(), DataRowComparer.Default).CopyToDataTable<DataRow>();
0
Madhu

以下のアプローチを試してください:

初期化:

var columnId = new DataColumn("ID", typeof (int));
var columnName = new DataColumn("Name", typeof (string));
var table1 = new DataTable();
table1.Columns.AddRange(new[] {columnId, columnName});
table1.PrimaryKey = new[] {columnId};
table1.Rows.Add(1, "A");
table1.Rows.Add(2, "B");
table1.Rows.Add(3, "C");

var table2 = table1.Clone();
table2.Rows.Add(1, "A");
table2.Rows.Add(2, "B");
table2.Rows.Add(4, "D");

解決:

var table3 = table1.Copy();
table3.AcceptChanges();
table3.Merge(table2);

var distinctRows = from row in table3.AsEnumerable()
                   where row.RowState != DataRowState.Modified
                   select row;

var distintTable = distinctRows.CopyToDataTable();

上記の解決策は、table1に存在しなかったtable2に新しい行がある場合にも機能します。

distintTable constains [〜#〜] c [〜#〜]および[〜#〜] d [〜#〜]

0
Ryszard Dżegan

以下をお試しください。これは基本的なものです。 2つのセットをマージして、違いを取得します。セットが正しく整列しない場合、これは機能しません。

DataSet firstDsData = new DataSet();
DataSet secondDsData = new DataSet();
DataSet finalDsData = new DataSet();
DataSet DifferenceDataSet = new DataSet();
finalDsData.Merge(firstDsData);
finalDsData.AcceptChanges();
finalDsData.Merge(secondDsData);
DifferenceDataSet = finalDsData.GetChanges();
0
TGarrett