tags:

views:

75

answers:

2

Getting a bit stuck on this. Basically I have a method that I want to return a predicate expression that I can use as a Where condition. I think what I need to do is similar to this: http://msdn.microsoft.com/en-us/library/bb882637.aspx but I'm a bit stuck as to what I need to do.

Method:

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 ??

}

Example Usage:

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

I need this separation so that I can pass my predicate into my repository and use it in other places.

+3  A: 

A predicate is only a function that returns a boolean value.

I can not test it, right now, but wouldn't this work ?

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;

}

EDIT : based on Matt's comments If you want to compose the delegates, you could proceed this way

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 ...*/);

}
tsimbalar
Yeah, just like this. Just extract the (x=>something) part from where and save it into Expression<Func<Conference, bool>>.
Euphoric
Cheers, but I want to build upon the filter/predicate. So if a keyword is passed in, add the filter for that. And if a venueId also passed in, add the filter for that... That's where it all confuses me...
Matt Roberts
And when you use the expression where you need the predicate, use exp.Compile()
Les
@Matt : ok then what you could do is build the Predicate piece by piece ... for instance, you could have a predicate for each of the fileds you check against and create a new predicate as the composition of all these ... I'll edit my answer ...
tsimbalar
Thanks, that works but I found the predicatebuilder link to be a nicer solution so I'll go with that, I'll +1 you for a correct sln though.
Matt Roberts
+1  A: 

Have you checked out PredicateBuilder

Matthew Abbott
Nice, does exactly what I want :)
Matt Roberts