1

我收集了一组具有各种属性(标题、发行年份、评级等)的电影,我需要使用 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部分来使搜索方法可重复用于所有不同类型的搜索?

4

3 回答 3

5

如何通过传入某种表达式或 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.
}
于 2012-11-03T19:31:52.443 回答
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
}

如果您对数据库使用它,则在您枚举之前它不会实际执行查询,因此这不会对您的数据库进行多次调用。

于 2012-11-03T19:38:21.387 回答
0

您可以使用CompiledQuery

检查这个非常有趣的答案。

希望能帮助到你。

于 2012-11-03T19:32:32.110 回答