【问题标题】:How to dynamically build and return a linq predicate based on user input如何根据用户输入动态构建和返回 linq 谓词
【发布时间】:2010-10-14 19:50:00
【问题描述】:

有点卡在这上面。基本上我有一个方法,我想返回一个可以用作 Where 条件的谓词表达式。 我认为我需要做的与此类似:http://msdn.microsoft.com/en-us/library/bb882637.aspx 但我对我需要做的事情有点困惑。

方法:

private static Expression<Func<Conference, bool>> GetSearchPredicate(string keyword, int? venueId, string month, int year)
{
    if (!String.IsNullOrEmpty(keyword))
    {
        // Want the equivilent of .Where(x => (x.Title.Contains(keyword) || x.Description.Contains(keyword)));
    }
    if (venueId.HasValue) 
    {
        // Some other predicate added...
    }

    return ??

}

示例用法:

var predicate = GetSearchPreducate(a,b,c,d);
var x = Conferences.All().Where(predicate);

我需要这种分离,以便我可以将我的谓词传递到我的存储库并在其他地方使用它。

【问题讨论】:

    标签: c# .net linq


    【解决方案1】:

    谓词只是一个返回布尔值的函数。

    我现在无法对其进行测试,但这不可行吗?

    private static Expression<Func<Conference, bool>> GetSearchPredicate(string keyword, int? venueId, string month, int year)
    {
        if (!String.IsNullOrEmpty(keyword))
        {
            //return a filtering fonction
            return (conf)=> conf.Title.Contains(keyword) || Description.Contains(keyword)));
        }
        if (venueId.HasValue) 
        {
            // Some other predicate added...
            return (conf)=> /*something boolean here */;
        }
    
        //no matching predicate, just return a predicate that is always true, to list everything
        return (conf) => true;
    
    }
    

    编辑:基于马特的 cmets 如果你想组成代表,你可以这样进行

    private static Expression<Func<Conference, bool>> GetSearchPredicate(string keyword, int? venueId, string month, int year)
    {   
        Expression<Func<Conference, bool> keywordPred = (conf) => true;
        Expression<Func<Conference, bool> venuePred = (conf) => true;
        //and so on ...
    
    
        if (!String.IsNullOrEmpty(keyword))
        {
            //edit the filtering fonction
            keywordPred =  (conf)=> conf.Title.Contains(keyword) || Description.Contains(keyword)));
        }
        if (venueId.HasValue) 
        {
            // Some other predicate added...
            venuePred =  (conf)=> /*something boolean here */;
        }
    
        //return a new predicate based on a combination of those predicates
        //I group it all with AND, but another method could use OR
        return (conf) => (keywordPred(conf) && venuePred(conf) /* and do on ...*/);
    
    }
    

    【讨论】:

    • 是的,就是这样。只需从 where 提取 (x=>something) 部分并将其保存到 Expression>.
    • 干杯,但我想建立在过滤器/谓词的基础上。因此,如果传入了关键字,请为此添加过滤器。如果还传入了一个venueId,请为此添加过滤器......这就是让我感到困惑的地方......
    • 当你在需要谓词的地方使用表达式时,使用 exp.Compile()
    • @Matt :好的,那么您可以做的是逐个构建谓词...例如,您可以为您检查的每个文件创建一个谓词并创建一个新谓词作为所有这些的组成......我将编辑我的答案......
    • 谢谢,这行得通,但我发现谓词生成器链接是一个更好的解决方案,所以我会继续这样做,不过我会为你 +1 正确的 sln。
    【解决方案2】:

    你签出PredicateBuilder

    【讨论】:

    • 很好,正是我想要的:)
    猜你喜欢
    • 1970-01-01
    • 2011-02-20
    • 2015-02-11
    • 1970-01-01
    • 2021-02-07
    • 1970-01-01
    • 1970-01-01
    • 2011-09-17
    • 2021-06-21
    相关资源
    最近更新 更多