2012-02-27 11 views
0

ラムダ式が新しく、エンティティのフレームワーククエリを表現する方法を見つけようとしています。私も間違っている可能性があり、私がしたいことをするためのより良い方法があります。これが本当なら、私に知らせてください。私のシナリオでは、私は高度な検索画面を持っています。ここでは、名前、顧客番号、または電話番号を検索することができます。あなたが望むならば1以上で検索することができます。私はバックエンドとしてEntity Frameworkを使用しており、テーブル用にリポジトリを設定しています。以下は、私がラムダ式の問題

Func<Parties, bool> exp; 

exp = null; 

if (vm.CustomerNumberCriteria != null) 
{ 
    custID = Convert.ToInt32(vm.CustomerNumberCriteria); 
    exp = o => o.ID == custID; 
} 


if (vm.NameCriteria != null) 

    exp += o => o.LastName.Contains(vm.NameCriteria) || o.FirstName.Contains(vm.NameCriteria) || o.MiddleName.Contains(vm.NameCriteria) || o.Designation.Contains(vm.NameCriteria); 

if (vm.PhoneNumberCriteria != null) 

    exp += o => o.CentralPhoneNumbers.Any(child => child.PhoneNumber == vm.PhoneNumberCriteria); 

//TODO set tempresults 
tempresults = custs.All.Where(exp).ToList(); 

私の問題を使用しようとしていますコードは、次のようにこれを扱うようだとし、検索条件のいずれかに一致するものがあれば、私は結果が必要です。

おかげ

答えて

3

二つの大きな問題がここにあります。まず、式ツリーではなくデリゲートを使用しています。つまり、テーブル全体がクライアントに引き戻され、そこでフィルタリングされます。あなたはExpression<Func<Parties, bool>>が欲しいです。今

、あなたが構築したい場合「または」発現木、最も簡単な方法は、PredicateBuilderを使用することです:

var predicate = PredicateBuilder.False<Parties>(); 

if (vm.CustomerNumberCriteria != null) 
{ 
    custID = Convert.ToInt32(vm.CustomerNumberCriteria); 
    predicate = predicate.Or(o => o.ID == custID); 
} 

if (vm.NameCriteria != null) 
{ 
    custID = Convert.ToInt32(vm.CustomerNumberCriteria); 
    predicate = predicate.Or(o => o.LastName.Contains(vm.NameCriteria) /* etc */) 
} 

if (vm.PhoneNumberCriteria != null) 
{ 
    predicate = predicate.Or(o => o.CentralPhoneNumbers.Any 
        (child => child.PhoneNumber == vm.PhoneNumberCriteria)); 
} 

tempresults = custs.All.Where(predicate).ToList(); 
+0

'式<締約国は、ブール値>' '式<のFunc <締約国である必要があり、ブール>> '、そう? – hvd

+0

@hvd:はい、タイプミス、申し訳ありません。一定。 –

+0

この回答を見ると、LinqKitをダウンロードしてPredicateBuilderを取得する必要があります。 Nugetを通してやるのはとても簡単でした。あなたのソリューションは私にとって素晴らしい仕事でした。私があなたの例から変えなければならなかった唯一のことは、私がcusts.All.AsExpandableと言っていた最後の行にあったということです。 –