可重用的LINQ查询,除了where子句

时间:2012-11-03 19:29:33

标签: c# linq

我有一系列具有各种属性(标题,发行年份,评级等)的电影,我需要使用LINQ查询进行搜索,如下所示:

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部分,使搜索方法可以重复用于所有不同类型的搜索?

3 个答案:

答案 0 :(得分: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.
}

编辑:我假设moviesIQueryable<T>,因为你在谈论Expression。如果它只是IEnumerable<T>,您需要:

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

    // Do common stuff with the matches.
}

答案 1 :(得分: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
}

如果你对数据库使用它,那么在你枚举之前它实际上不会执行查询,所以这不会对你的数据库进行多次调用。

答案 2 :(得分:0)

您可以使用CompiledQuery

在SO上查看this非常有趣的答案。

希望它有所帮助。