我有這樣的功能:添加和語句表達<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.
我有這樣的功能:添加和語句表達<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.
喜歡的東西
Find(x => x.Id == 4 && x.Secured == false);
表達必須是 「打開」 和改建,像這樣:
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()
與&&
條件)
你的問題是,你想訪問通用方法中的T
的成員。因爲T
可能沒有Secured
成員,因此編譯器不會讓您訪問Secured
,因此T
可能是此時的任何內容。
您可以將T
轉換爲dynamic
,但這只是將編譯時錯誤更改爲運行時錯誤(加上它很可怕)。
最好的辦法是確保T
實現一些已知的具有Secured成員的接口。
public List<T> Find(Expression<Func<T, bool>> query) where T : ISecured
或者使用表達式目錄樹作爲薩那託斯提示:)再次,這舉動儘管如此,運行問題。 – GazTheDestroyer
它在那裏沒有,你可以有them.'Statement.Where(查詢)。凡(X => x.Secured!)的倍數;' – Ralf