2012-05-24 10 views
6

私はリストを持っています。私はリストのすべてのデータテーブルにあるすべての行を見つけるためにテーブルのリスト内のすべての行をフィルタリングしたいと思います。DataTableのリスト内で交差するDataRowを見つける

可能であれば、比較はすべての行にある「ID」列にある必要があります。

私はLinqでこれを解決しようとしましたが、固まってしまいました。これはこれまで私が持っているものです:

List<DataTable> dataTables = new List<DataTable>(); 

// fill up the list 
List<DataRow> dataRows = 
    dataTables.SelectMany(dt => dt.Rows.Cast<DataRow>().AsEnumerable()). 
    Aggregate((r1, r2) => r1.Intersect(r2)); 

何か提案がありますか?

+0

私は過去にIntersectを使用していましたが、いつの間にか平等比較が行われていました。プリミティブ型のEnumerablesで作業していましたが、通常は大丈夫ですが、 。あなたがまだしていないか調べる価値がある – SpaceBison

答えて

4

ない素朴な疑問。ここに解決策があります(それは私にとっては複雑すぎるようですが、機能します)。

  • 全て共通の値
  • のいずれかを持っているすべての行の行の単一の発生を探すために複数のリスト交差するデータセット
  • へのLINQを使用して、各列からID値を取得します一致するID

DataTableでLinqを使用するには、this articleを参照してください。あなたは

var setsOfIds = dataTables.Select (
    t => t.AsEnumerable().Select (x => x.Field<int>("ID")).OfType<int>()); 

この

var ids = dt.AsEnumerable().Select (d => d.Field<int>("ID")).OfType<int>(); 

のような一つのテーブルから複数のテーブルからIDが複数のリストを交差するために得ることができる

this articleを試してみてください。そこのメソッドの1つを使用すると、すべてのIDの共通部分を取得できます。

var rows = dataTables.SelectMany (t => t.AsEnumerable()).Where(
    r => commonIds.Contains(r.Field<int>("ID"))); 

グループ:ジョンスキートのヘルパーメソッド

public static class MyExtensions 
{ 
    public static List<T> IntersectAll<T>(this IEnumerable<IEnumerable<T>> lists) 
    { 
     HashSet<T> hashSet = new HashSet<T>(lists.First()); 
     foreach (var list in lists.Skip(1)) 
     { 
      hashSet.IntersectWith(list); 
     } 
     return hashSet.ToList(); 
    } 
} 

を使用して

我々は今、共通のIDでのDataTableとフィルタからすべての行を平ら

var commonIds = setsOfIds.InsersectAll(); 

を書くことができますidによって、各行の最初のインスタンスを取得します。

var result = rows.GroupBy (r => r.Field<int>("ID")).Select (r => r.First()); 
1

2つのリストの間の交差点を見つけるために、これを試してみてください:

r1.Join(r2, r1 => r1.Id, r2 => r2.Id, (r1, r2) => r1); 
関連する問題