6

私はリストを持っています。リスト内のすべてのデータテーブルにあるすべての行を見つけるために、テーブルのリスト内のすべての行をフィルター処理したいと思います。

可能であれば、すべての行にある「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));

助言がありますか?

4

2 に答える 2

4

簡単な質問ではありません。これが解決策です(私には複雑すぎるようですが、うまくいきます)。

  • Linq to DataSets を使用して各行から Id 値を取得する
  • 複数のリストを交差させて、すべての共通値を見つけます
  • 一致する ID の 1 つを持つすべての行で、1 つの行を見つけます

DataTable で Linq を使用するには、まずこの記事を参照してください。

このように1つのテーブルからIDを取得できます

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

および複数のテーブルから

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

複数のリストを交差させるには、この記事を試してください。そこにあるメソッドの 1 つを使用すると、すべての ID の共通部分を取得できます。

Jon Skeet のヘルパー メソッドの使用

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

私たちは書くことができます

var commonIds = setsOfIds.InsersectAll();

次に、DataTables からすべての行をフラット化し、共通 ID でフィルター処理します。

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

ID でグループ化し、各行の最初のインスタンスを取得します。

var result = rows.GroupBy (r => r.Field<int>("ID")).Select (r => r.First ());
于 2012-05-24T14:49:04.200 に答える
1

これを試して、2つのリスト間の共通部分を見つけてください。

r1.Join(r2, r1 => r1.Id, r2 => r2.Id, (r1, r2) => r1);
于 2012-05-24T13:16:21.667 に答える