19

これが可能かどうか、または探しているものを正しく表現しているかどうかはわかりませんが、ライブラリに次のコードが繰り返しあり、DRYを練習したいと思います。Googleの単純なユーザー指定の検索フィールドに基づいてクエリを実行しているSQLServerテーブルのセットがあります。LINQを使用して、検索文字列の内容に基づいて最終的なクエリを作成しています。ジェネリックスを使用し、ラムダ関数を渡して、これから再利用可能なルーチンを作成する方法を探しています。

string[] arrayOfQueryTerms = getsTheArray();

var somequery = from q in dataContext.MyTable
                select q;

if (arrayOfQueryTerms.Length == 1)
{
    somequery = somequery.Where<MyTableEntity>(
        e => e.FieldName.StartsWith(arrayOfQueryTerms[0]));
}
else
{
    foreach(string queryTerm in arrayOfQueryTerms)
    {
        if (!String.IsNullOrEmpty(queryTerm))
        {
            somequery = somequery 
                        .Where<MyTableEntity>(
                            e => e.FieldName.Contains(queryTerm));
        }
    }
}

次のようなシグネチャを持つジェネリックメソッドを作成したいと思っていました。

private IQueryable<T> getQuery(
    T MyTableEntity, string[] arrayOfQueryTerms, Func<T, bool> predicate)

私はすべてのテーブルで同じ検索戦略を使用しているため、使用法ごとに実際に異なるのは、検索されたMyTableとMyTableEntityと検索されたFieldNameだけです。これは意味がありますか?LINQを使用して、where句でクエリするフィールドの名前を動的に渡す方法はありますか?または、これを述語ラムダとして渡すことはできますか?

e => e.FieldName.Contains(queryTerm)

SQLでこれを行うには、おそらくもっと簡単な方法が100万通りあることを私は理解していますが、これのためにLINQファミリーのすべてを維持したいと思います。また、このような問題にはジェネリックスが便利だと思います。何か案は?

4

5 に答える 5

15

DynamicLinqを探しているようです。こちらをご覧ください。これにより、次のように文字列を引数としてクエリメソッドに渡すことができます。

var query = dataSource.Where("CategoryID == 2 && UnitPrice > 3")
                      .OrderBy("SupplierID");

編集:C#4の動的サポートを使用したこのテーマに関する別の投稿セット:パート1パート2

于 2008-09-24T04:29:11.123 に答える
7

基本的に条件付き述語ビルダーが必要なようです。

これをあなたが探しているものに形作ることができることを願っています、頑張ってください!

http://www.albahari.com/nutshell/predicatebuilder.aspx

于 2008-09-24T04:25:59.603 に答える
6

式ツリーを見たいと思うかもしれません:

IQueryable<T> getQuery<T>(T myTableEntity, string[] arrayOfQueryTerms, Expression<Func<T, bool>> predicate)
 { var fieldOrProperty = getMemberInfo(predicate);
   /* ... */
 }

MemberInfo getmemberInfo<T>(Expression<Func<T,bool> expr)
 { var memberExpr = expr as MemberExpression;
   if (memberExpr != null) return memberExpr.Member;
   throw new ArgumentException();
 }

var q = getQuery<FooTable>(foo, new[]{"Bar","Baz"}, x=>x.FieldName);
于 2008-09-24T04:32:46.730 に答える
0

私は最近、これと同じことをしなければなりませんでした。ここでDynamic Linq が必要になります。これは、これを強く型付けしておく方法です。

于 2008-11-08T21:16:58.320 に答える
0

Gridifyライブラリを試すことをお勧めします。作業がはるかに簡単になり、パフォーマンスも向上します。

使用例:

query = dataSource.ApplyFiltering("FiledName=John");

これは、動的 LINQ ライブラリ間のパフォーマンス比較です。 ここに画像の説明を入力

于 2021-09-18T13:00:48.873 に答える