2012-02-27 92 views
0

我是lambda表達式的新手,我在試圖弄清楚如何在一個表示我的實體框架查詢時遇到問題。我也可能是錯的,只有更好的方法去做我想做的事。如果這是真的,請讓我知道。我的方案是我有一個高級搜索屏幕,您可以選擇搜索名稱,客戶號碼或電話號碼。如果你願意,你可以搜索超過1個。我使用實體框架作爲我的後端,併爲我的表設置了存儲庫。下面是我想使用lambda表達式問題

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

'表達<締約方,布爾>'應該是'表達>',對嗎? – hvd 2012-02-27 17:44:20

+0

@ hvd:對,錯字,對不起。固定。 – 2012-02-27 17:45:44

+0

對於anyoen看這個答案,你必須下載LinqKit來獲得PredicateBuilder。通過Nuget很容易做到。您的解決方案對我來說非常棒。我必須改變你的例子的唯一的東西是最後一行,我不得不說custsA.AsExpandable.Where,但我認爲,因爲我的數據來自實體框架。 – 2012-02-28 14:53:13