2011-08-12 56 views
0

我需要傳入將在方法中的LINQ查詢中使用的「where」lambda表達式。問題是,我不知道在何處進行比較,直到進入方法。構建一個lambda WHERE表達式以傳入方法

現在來進一步解釋和澄清我上面所說的一些,我會想出一個人爲的例子。

想象一下,我有一個List<Products>,我需要使用Products對象的productId屬性將該列表縮小爲單個記錄。通常我會做到這一點:

var product = productList.Where(p=>p.productId == 123).FirstOrDefault(); 

現在走了一步 - 我需要把上述邏輯到未侷限於List<Products>,但不是List<T>所以最好的方法,我會調用它像這樣(我知道下面將無法正常工作,它只是這裏要說明什麼,我試圖實現):

myMethod(productList, p => p.productId == X) 

隨着告誡在於X是不知道,直到我在方法裏面。

最後,對於它的價值,我需要指出我的數據收集是一個OData DataServiceQuery。因此,重新總結我的問題:我需要知道如何構建一個lambda「where」表達式,我可以將它傳遞給一個方法,以及如何在LINQ查詢中將它用於對象集合。

+0

T始終具有productId屬性? – sll

+0

不,產品ID不一定是屬性。有時我可能有一個用戶列表,所以它將是UserId,或者可能是一組公司對象的companyId。 – bugfixr

回答

2

myMethod的(productList的,P => p.productId == X) - 你可以用這一招

static void myMethod<T>(List<T> list, Func<T,bool> predicate, ref int x) 
    { 
     x = 5; 
     var v = list.Where(predicate); 
     foreach (var i in v) 
      Console.Write(i); 
     Console.ReadLine(); 
    } 

    static void Main(string[] args) 
    { 
     List<int> x = new List<int> { 1, 2, 3, 4, 5 }; 
     int z = 0; 
     myMethod(x, p => p == z, ref z); 
    } 

但不知道模仿,如果它解決了在整個

+0

有趣的想法!如果你看到這個實現的地方,你會認爲它是一個黑客? – bugfixr

+0

還沒有看到它的實施,但它不是一個破解,從語法的角度來看這是非常合法的 – elevener

0

你可以嘗試你的問題使用免費LinqKit庫中的PredicateBuilder類(tutorial)。

然後可以構建使用

PredicateBuilder predicate = PredicateBuilder.True<T>(); 
predicate = PredicateBuilder.And(predicate, p=> p.product_id == X); 

其中X是類型T的

可以使用此謂詞在where子句中如.Where(predicate)並返回一個IQueryable或返回謂詞本身的謂詞這將是類型Expression<Func<T, bool>>

2

首先,如果您要查詢IEnumerable<T>,您將需要確保您的比較將首先工作。在這種情況下,你可以讓你的對象實現一個接口,保證它們將支持比較。

一旦你這樣做,你的方法可以有一個通用的約束,限制對這些接口的輸入。在這一點上,你的方法可以採取Func鍵,它可以傳遞到LINQ Where子句:

public interface Identifier 
{ 
    int Id { get; set; } 
} 

public class Product : Identifier 
{ 
    public int Id { get; set; } 
    //Other stuff 
} 

public T GetMatch<T>(IEnumerable<T> collection, Func<T, int, bool> predicate) where T : Identifier 
{ 
    int comparison = 5; 
    return collection.Where(item => predicate(item, comparison)).FirstOrDefault(); 
} 

可以調用,如:

var match = GetMatch<Identifier>(collection, (x, y) => x.Id == y); 

UPDATE: 我修改了上面代碼採取比較參數

+0

感謝戴夫 - 主要問題是,雖然我不知道5的值,直到方法執行。 – bugfixr

+0

@Chu - 是值(在提供的示例中爲5),它將作爲參數傳入GetSubcollection方法中?值如何進入函數範圍內? – davecoulter

+0

@Chu - 我在上面添加了一個參數,以顯示如何將比較值添加到Func <> – davecoulter