2013-09-23 104 views
2

我想寫類似下面的代碼 -傳遞參數給LINQ謂詞

public IQueryable<Invoice> InvoiceFilterForMonthAndYear(DateTime? monthAndYear = null) 
    { 
     var invoices = _invoices.Where(MonthAndYearPredicate(monthAndYear); 
     return invoices; 
    } 

    private bool MonthAndYearPredicate(Invoice invoice, DateTime? monthAndYear) 
    { 
     //code to check if the invoice start or end dates is from the falls in the month I am checking for 
    } 

但由於謂詞預計只有一個參數,我不能使用謂詞這樣。

我知道我可以寫InvoiceFilterForMonthAndYear的Where子句來完成這項工作,但是我想把比較邏輯放到它自己的方法中。

+0

'我=> MonthAndYearPredicate(I,monthAndYear)' – Marc

+0

@ USER1這將編譯,但查詢供應商將無法處理的。 – Servy

+0

啊,都是LTE。錯過了標籤。 – Marc

回答

3

它的工作原理,如果你的比較方法返回一個表達式:

private Expression<Func<Invoice,bool>> MonthAndYearPredicate(
    DateTime? monthAndYear) 
{ 
    return i => i.StartDate >= monthAndYear; // or whatever 
} 

被稱爲像在您的示例:

var invoices = _invoices.Where(MonthAndYearPredicate(monthAndYear)); 

或者你也可以提取邏輯成IQueryable<Invoice>擴展方法:

public static class QueryExtensions 
{ 
    public static IQueryable<Invoice> WhereMonthAndYear(
     this IQueryable<Invoice> query, DateTime? monthAndYear) 
    { 
     return query.Where(i => i.StartDate >= monthAndYear); // or whatever 
    } 
} 

要這樣調用:

var invoices = _invoices.WhereMonthAndYear(monthAndYear); 

請記住,在這兩種情況下,您必須使用EF可以轉換爲SQL的有效LINQ-to-Entities表達式。它只會使表達式可以針對不同的查詢重用,但不會擴展其功能。

-1

您將無法將邏輯提取到方法中。如果這樣做,那麼由方法調用產生的表達式樹將沒有足夠的信息供查詢提供者生成查詢。您需要內聯邏輯,以便它們都在表達式樹中結束。