2017-12-18 6 views
0

次のTuplesのリストは、ヘッダー/列名とその列にある値のリストで構成されています。私は次にリスト全体をDataTableに照会したいと思う。動的テーブルクエリ

List<Tuple<string, IEnumerable<string>>> filters = new List<Tuple<string, IEnumerable<string>>>(); 

ここでは、それぞれを別々のクエリとして実行し、1つずつループでフィルタリングしています。しかし、私は複数のクエリをループしたり実行したりすることなく、これを行う方法があるはずだと思います。私。一度にすべてのクエリをまとめて適用します。

var dataTemp = MyDataTable.AsEnumerable(); 
foreach (var filter in filters) 
{ 
datTemp = datTemp.Where(row => filter.Item2.Contains(row.Field<String>(filter.Item1))); 
} 
return dataTemp; 

答えて

1

あなたはすべてのフィルタに対して、各行をテストすることができるはずです。

var dataTemp = MyDataTable.AsEnumerable() 
        .Where(row => filters.All(filter => filter.Item2.Contains(row.Field<string>(filter.Item1)))); 

DependiあなたのフィルタIEnumerable<string>の性質にngの、あなたがより速く処理するためのフィルタを変換することもできます。

var fastFilters = filters.Select(f => (f.Item1, new HashSet<string>(f.Item2))); 

var dataTemp = MyDataTable.AsEnumerable() 
        .Where(row => fastFilters.All(filter => filter.Item2.Contains(row.Field<string>(filter.Item1)))); 

私は通常HashSetIEnumerable<>を変換するための拡張機能を使用します。

public static HashSet<T> ToHashSet<T>(this IEnumerable<T> source) => new HashSet<T>(source); 

次に、あなたがすることができますhave

var fastFilters = filters.Select(f => (f.Item1, f.Item2.ToHashSet())); 
0

ここでLINQクエリです:

filters.Aggregate(dataTemp, 
      (current, filter) => current.Where(row => filter.Item2.Contains(row.Field<string>(filter.Item1)))); 

あなたはまた、おそらく拡張メソッドを実装することができます

public static EnumerableRowCollection<DataRow> CustomFilter(this DataTable @this, 
     IEnumerable<Tuple<string, IEnumerable<string>>> filters) 
    { 
     var dataTemp = @this.AsEnumerable(); 
     return filters.Aggregate(dataTemp, 
      (current, filter) => current.Where(row => filter.Item2.Contains(row.Field<string>(filter.Item1)))); 
    } 
関連する問題