2番目のデータテーブルにない最初のデータテーブルの行を取得するために、2つのデータテーブルを減算する方法はありますか?
以下のような .Except() メソッドを試しましたが、うまくいきません。
dt1.AsEnumerable().Except(dt2.AsEnumerable()).CopyToDataTable();
私はこの方法の使用に間違いがあると思いますが、それを見つけることができませんでしたか?
IEquailtyComparerを使用して独自の Comparer を作成できます
public class CustomDataRowComparer : IEqualityComparer<DataRow>
{
public bool Equals(DataRow x, DataRow y)
{
for (int i = 0; i < x.Table.Columns.Count; i++)
{
if (x[i].ToString() != y[i].ToString())
{
return false;
}
}
return true;
}
public int GetHashCode(DataRow obj)
{
return obj.ToString().GetHashCode();
}
}
後で次のように呼び出すことができます。
CustomDataRowComparer myDRComparer = new CustomDataRowComparer();
var result2 = dt1.AsEnumerable().Except(dt2.AsEnumerable(),myDRComparer).CopyToDataTable();
Except
参照が異なるため、機能しません。メモリ内のデータ行の各「コピー」は異なるオブジェクトであるため、 で行われる等値比較Except
は常に false を返します。
行 ID など、同等のものと比較する必要があります。これを行う方法のいくつかのアイデア:
var rowsInFirstNotInSecond = dt1.Rows.Where(r1=>!dt2.Rows.Any(r2=>r1.ID == r2.ID));
または:
var rowsInFirstNotInSecond = dt1.Rows.Where(r1=>dt2.FindById(r1.ID) == null);
このコードは確実に機能します:
var rows =dtFirst.AsEnumerable().Except(dtSecond.AsEnumerable(), DataRowComparer.Default);
DataTable result = null;
if (rows.Count() != 0)
result = rows.CopyToDataTable();
次のコードを使用して、2 つのデータテーブルを互いに減算しました。
var query =
from row1 in dt1
where !(from row2 in dt2
select row2.ID)
.Contains(row1.ID)
select row1;
このコードは、私が望むものを正確に返します...