2011-08-19 11 views
0
 DataTable dt1 = new DataTable(); 
     DataTable dt2 = new DataTable(); 

     dt1.Columns.Add("id"); 
     dt2.Columns.Add("id"); 

     dt1.Columns.Add("val1"); 
     dt2.Columns.Add("val1"); 

     dt1.Columns.Add("val2"); 
     dt1.Columns.Add("val2"); 


     dt1.Rows.Add(new string[] { "1", "a", "a1" }); 
     dt1.Rows.Add(new string[] { "2", "b", "b1" }); 
     dt1.Rows.Add(new string[] { "", "b", "b1" }); 
     dt1.Rows.Add(new string[] { "4", "", "c1" }); 


     dt2.Rows.Add(new string[] { "1", "a", "a1" }); 
     dt2.Rows.Add(new string[] { "2", "b", "b1" }); 
     dt2.Rows.Add(new string[] { "3", "c", "c1" }); 
     dt2.Rows.Add(new string[] { "3", "c", "c1" }); 
     dt2.Rows.Add(new string[] { "4", "d", "d1" }); 
     dt2.Rows.Add(new string[] { "5", "e", "e1" }); 

結果にはdt1に存在しない値のみを含める必要があります。我々はLINQ2つのDataTable Multiフィールドを比較します

+1

データテーブルを使用する必要がありますか? –

答えて

1

はいでこれを行うことができ、あなたはLINQでこれを行うことができ、私はこれを行うだろう:これはあなたに比較することができる匿名型のIEnumerable<T>を与える

var dataRows1 = st1.AsEnumerable().Select(r => new { 
    Id = r["id"], Val1 = r["val1"], Val2 = r["val2"] }); 

var dataRows2 = st2.AsEnumerable().Select(r => new { 
    Id = r["id"], Val1 = r["val1"], Val2 = r["val2"] }); 

。これはあなたの比較基準が行(idを含む)のすべての値であることを前提としていることを

var dt2NotInDt1 = dataRows2.Where(r2 => !dataRows1.Any(r1 => r1.Equals(r2)); 

注:その後、あなたはこれを行うことができます。

Equalsへの呼び出しにも注意してください。匿名型は、Equalsメソッドをオーバーライドして、匿名型のすべてのプロパティにわたって値の比較を提供します。 "Anonymous Types" section of the C# Programming Guideから:匿名型のEqualsGetHashCode方法が が プロパティのEqualsGetHashcode方法で定義されているため

、同じ匿名型の2つのインスタンスが等しいだけ もしそれらのすべてのプロパティがありますは同じ。

制約がどのようなものであるかによって、このロジックを簡素化できます。たとえば、プライマリキー(または一意の行識別子)がある場合は、その値をキーとする辞書に行を配置し、それに基づいてルックアップを実行できます。あなたのケースでは

は、idが一意であると仮定すると、あなたは(一番上の最初の二行の後に)これ​​を行うことができます:

var dataRows1Map = dataRows1.ToDictionary(r => r.Id); 

あなたが、その後(上の検索を行うことができますマップを与えること私はここで少し読めると信じているように、クエリの構文に切り替わります)。

var dt2NotInDt1 = 
    for r2 in dataRows2 
    let r1Exists = dataRows1Map.ContainsKey(r2.Id) 
    let r1 = r1Exists ? dataRows1Map[r2.Id] : null 
    where 
     // Rows that don't have a primary key in the first set. 
     !r1Exists || 
     // Rows that are different. 
     !r1.Equals(r2) 
    select r2; 
関連する問題