Search code examples
dynamiclambdaexpression-trees

Dynamic expression tree how to


Implemented a generic repository with several Methods. One of those is this:

public IEnumerable<T> Find(Expression<Func<T, bool>> where)
        {
            return _objectSet.Where(where);
        }

Given <T> to be <Culture> it is easy to call this like this:

Expression<Func<Culture, bool>> whereClause = c => c.CultureId > 4 ;

return cultureRepository.Find(whereClause).AsQueryable();

But now i see (realize) that this kind of quering is "limiting only to one criteria". What i would like to do is this:

in the above example c is of type Culture. Culture has several properties like CultureId, Name, Displayname,... How would i express the following: CultureId > 4 and Name.contains('de') and in another execution Name.contains('us') and Displayname.contains('ca') and ....

Those queries should be created dynamically. I had a look in Expression trees (as i thought this to be a solution to my problem - btw i never used them before) but i cannot find anything which points to my requirement.

How can this be costructed?

Thanks in advance


Solution

  • Codeka gave me a hint for re-thinking my statement, regarding this limitation to one parameter.

    Turns out it very easy to implement a scenario with all the properties we want to query, which have values. For example if the Cutlure type is defined with 3 properties

    Name string

    Displayname string

    CultureId int

    than one can implement a Filter-Expression like this

    Expression<Func<Culture, bool>> whereClause = c => (
                    (!String.IsNullOrEmpty(FilterCulture.Name) ? c.Name.Contains(FilterCulture.Name) : true) &&
                    (!String.IsNullOrEmpty(FilterCulture.Displayname) ? c.Displayname.Contains(FilterCulture.Displayname) : true) &&
                    (FilterCulture.CultureId > 0 ? c.CultureId == FilterCulture.CultureId : true)
                    );
    

    As you can see i 'm using the && operator between each property to narrow the results (one could use the || to widen the results - thus implementing OR).

    Thank you again codeka !