7

コンパイルされたメソッドを一緒に追加できることがわかりました。

Expression<Func<Customer, bool>> ln = c => c.lastname.Equals(_customer.lastName, StringComparison.InvariantCultureIgnoreCase);
Expression<Func<Customer, bool>> fn = c => c.firstname.Equals(_customer.firstName, StringComparison.InvariantCultureIgnoreCase);
Expression<Func<Customer, bool>> fdob = c => c.DOB.ToString("yyyyMMdd").Equals(_customer.DOB.ToString("yyyyMMdd"));

var filter = ln.Compile() + fn.Compile() + fdob.Compile();

これを行うのは理にかなっていますか?

ラムダ式の代わりにフィルターを使用して、顧客のリポジトリをフィルター処理するつもりです。

IEnumerable<Customer> customersFound = _repo.Customers.Where(filter);

ビジネス ロジックに応じて、3 つのコンパイル済みメソッドを一緒に追加する場合と追加しない場合がありますが、必要に応じて選択し、さらにコンパイル済みメソッドを追加することもできます。

それらを一緒に追加するとクエリ文字列が作成されるかどうかを誰かが説明できますか? 誰かがより良い提案を得ましたか?

「Where」ステートメントを連鎖させて通常のラムダ式を使用することもできますが、メソッドをコンパイルしてそれらを追加することで得られるものに興味をそそられます!

4

3 に答える 3

3

述語を連鎖させるのは創造的な努力であり、残念なことにうまくいきません。その理由は、Lasse と Nicholas (+2) によって見事に説明されています。しかし、あなたはまた尋ねます:

誰かがより良い提案を得ましたか?

コンパイルされた式の欠点は、それらがもはや式ではないため、IQueryableSQL クエリ プロバイダー (linq to sql または linq to entities など) によってサポートされている s では使用できないことです。私_repo.Customersはそのようなものだと思いIQueryableます。

式を動的に連鎖させたい場合、LINQKit のPredicateBuilder はこれを行うための優れたツールです。

var pred = Predicate.True<Customer>();

pred = pred.And(c => c.lastname.Equals(_customer.lastName, StringComparison.InvariantCultureIgnoreCase);
pred = pred.And(c => c.firstname.Equals(_customer.firstName, StringComparison.InvariantCultureIgnoreCase);
pred = pred.And(c => c.DOB.ToString("yyyyMMdd").Equals(_customer.DOB.ToString("yyyyMMdd"));

var customersFound = _repo.Customers.Where(pred.Expand());

Expand目的は次のとおりです。

Entity Framework のクエリ処理パイプラインは呼び出し式を処理できないため、クエリの最初のオブジェクトで AsExpandable を呼び出す必要があります。AsExpandable を呼び出すことで、呼び出し式を Entity Framework が理解できるより単純な構造に置き換える LINQKit の式ビジター クラスをアクティブにします。

または: それがないと式がInvoked になり、EF で例外が発生します。

LINQ 式ノード タイプ 'Invoke' は、LINQ to Entities ではサポートされていません。

ところで。linq to sql/entities を使用する場合c.lastname == _customer.lastNameは、SQL に変換され、データベース照合で大文字と小文字が区別されるため、使用することもできます。

于 2013-03-30T20:17:27.740 に答える