c# - Combine property selector expression tree and value to create a predicate for EF filtering - create filter from lambda selector and value -
given simple class arbitrary properties (for discussion lets id, name, , description)
and given instance of class, want find matching entries in database specifying property match
i'm trying in respect similar addorupdate method of ef, need entity returned me further processing.
var match = new someclass{name="whatever"}; var found = context.someclass.find(x=>x.name, match); public static t find<t>(this dbset<t> set, expression<func<t, object>> matchon, t matchagainst) t : class { var func = matchon.compile(); var valuetofind = func(matchagainst); var combinedexpression = //matchon + "=" + valuetofind; var found = set.firstordefault(combinedexpression); return found; } that gives me value of property in passed in object, need combine value passed in expression , pass db set.
ie, code i'm trying run set.firstordefault(x=>x.name==valuetofind) how take matchon expression (which contains x=>x.name) , combine ==valuetofind x=>x.name==valuetofind them?
how build combined expression? (i realize "string" code above wrong, trying across need function do, have no idea syntax like.)
for manually coded examples, easy enough pass in hardcoded lambda value set, use case involves running through collection of objects , finding match each one, value not known until runtime, , method must work against arbitrary types , various properties, can't hardcode property name either.
if have property selector, , value compare to, can expression tree this:
public static func<tentity, bool> getcomparer<tentity,tproperty>( expression<func<tentity,tproperty>> selector, tproperty value) { var propertyref = selector.body; var parameter = selector.parameters[0]; var constantref = expression.constant(value); var comparer = expression.lambda<func<tentity, bool>> (expression.equal(propertyref, constantref), parameter) .compile(); return comparer; } sample usage:
var comparer = getcomparer<person, string>(p => p.name, "john"); var persons = person.getpersons(); var john = persons.firstordefault(comparer);
Comments
Post a Comment