2012-11-03 124 views
1

如下我有具有各種屬性,我需要搜索使用LINQ查詢電影(標題,發行年份,等級,等等)的集合:可重複使用LINQ查詢除了where子句

public BindingList<Movie> SearchByTitle(string title) 
{ 
    var matches = from movies in movieCollection 
        where movies.Title == title 
        select movies; 
    // do some other stuff with the matches 
} 

但我不想要一個單獨的方法來搜索每個屬性,因爲搜索之間的唯一變化是where部分。例如where movies.Rating == ratingwhere movies.ReleaseYear == releaseYear。如何通過傳遞ExpressionFunc作爲where部分來對所有不同類型的搜索重複使用搜索方法?

回答

5

如何通過傳遞某種Expression或Func作爲where部分來使搜索方法對所有不同種類的搜索都可重用?

您的查詢確實不是什麼以外的where子句。但是你可以很容易地將where部分配置成...只是不使用查詢表達式。

public BindingList<Movie> SearchByTitle(Expression<Func<Movie, bool>> predicate) 
{ 
    var matches = movies.Where(predicate); 

    // Do common stuff with the matches. 
} 

編輯:我假設movies是一個IQueryable<T>,因爲你在談論Expression。如果它只是一個IEnumerable<T>,你想:

public BindingList<Movie> SearchByTitle(Func<Movie, bool> predicate) 
{ 
    var matches = movies.Where(predicate); 

    // Do common stuff with the matches. 
} 
+0

這很好,但我需要使用'var matches = movies.Where(predicate.Compile());' – Brett

+0

@Brett:將編輯這個... –

0

你可以使用一個CompiledQuery

檢查this對SO很有意思的答案。

希望它有幫助。

1

您可以使用擴展方法(在靜態類中定義這個)

public static IQueryable<T> AddSearchParameter<T>(this IQueryable<T> query, bool condition, System.Linq.Expressions.Expression<Func<T, bool>> predicate) 
    { 
     if (condition) 
     { 
      query = query.Where(predicate); 
     } 

     return query; 
    } 

因此,例如:如果你使用這種針對數據庫

public BindingList<Movie> Search(string title, int? year, int? rating) 
{ 
    var matches = movieCollection.AddSearchParameter(!string.IsNullorEmpty(title), m=>m.Title == title); 
    matches = matches.AddSearchParameter(year.HasValue, m=>m.Year == year.Value); 
    matches = matches.AddSearchParameter(rating.HasValue, m=>m.rating >= rating.Value); 

    // do some other stuff with the matches 
} 

也不會真正執行查詢,直到您枚舉,這樣不會多次調用您的數據庫。