2015-05-26 48 views
1

我有這樣的功能:添加和語句表達<Func鍵<T, bool>>

public List<T> Find(Expression<Func<T, bool>> query) 
{ 
} 

Find(x => x.Id == 4); 

裏面我想鏈And條件的方法Find。 類似:

query.And(x => x.Secured == false);//Secured is a memeber inside T like Id. 
+2

它在那裏沒有,你可以有them.'Statement.Where(查詢)。凡(X => x.Secured!)的倍數;' – Ralf

回答

-3

喜歡的東西

Find(x => x.Id == 4 && x.Secured == false); 
0

表達必須是 「打開」 和改建,像這樣:

public List<T> Find<T>(Expression<Func<T, bool>> query) 
{ 
    ParameterExpression parameter = query.Parameters[0]; 
    Expression body = query.Body; 

    MemberExpression property = Expression.Property(parameter, "Secured"); 

    body = Expression.AndAlso(body, Expression.Not(property)); 

    Expression<Func<T, bool>> query2 = Expression.Lambda<Func<T, bool>>(body, parameter); 

    // Now you can use query2 

    return null; 
} 

請注意,我在考慮這個x.Secured == false是相當於!x.Secured。顯然Secured可能是一個奇怪的類,它重載==運算符,但我會忽略這種情況。

正如@Ralf所建議的,你甚至可以簡單地做兩個.Where。像:

public List<T> Find<T>(Expression<Func<T, bool>> query) 
{ 
    ParameterExpression parameter = query.Parameters[0]; 

    MemberExpression property = Expression.Property(parameter, "Secured"); 

    Expression<Func<T, bool>> query2 = Expression.Lambda<Func<T, bool>>(Expression.Not(property), parameter); 

    return context.Set<T> 
     .Where(query) 
     .Where(query2) 
     .ToList(); 
} 

(我使用的是作爲一個例子context.Set<T>,這是非常相似的,如果你正在使用實體框架,你會做什麼,但一般幾乎所有的IQuerable<>/IEnumerable<>處理將兩個.Where()像一個單一的.Where()&&條件)

1

你的問題是,你想訪問通用方法中的T的成員。因爲T可能沒有Secured成員,因此編譯器不會讓您訪問Secured,因此T可能是此時的任何內容。

您可以將T轉換爲dynamic,但這只是將編譯時錯誤更改爲運行時錯誤(加上它很可怕)。

最好的辦法是確保T實現一些已知的具有Secured成員的接口。

public List<T> Find(Expression<Func<T, bool>> query) where T : ISecured 
+0

或者使用表達式目錄樹作爲薩那託斯提示:)再次,這舉動儘管如此,運行問題。 – GazTheDestroyer

相關問題