c# - LINQ Filter Implementation with Expressions -
in mvc4 , providing search box user search value in table. implementing generic filter condition @ server side in c#
need combine multiple expressions form single expression
expression<func<t, bool>>
for example
table columns
menutext, role name (role.name mapping), actionname
now if user entered in search box abc , can in of rows in shown columns, need filter.
model
public class menu { public string menutext {get;set;} public role role {get;set;} public string actionname {get;set;} } public class role { public string name {get;set;} }
so far have implemented
/// <summary> /// string[] properties property.name (menutext, actionname), including deeper mapping names such (role.name) /// </summary> public static expression<func<t, bool>> filterkey<t>(string filtertext, params string[] properties) { parameterexpression parameter = expression.parameter(typeof (t)); expression[] propertyexpressions = properties.select( x => !string.isnullorempty(x) ? getdeeppropertyexpression(parameter, x) : null).toarray(); expression<func<t, bool>> predicate = predicatebuilder.false<t>(); foreach (expression expression in propertyexpressions) { var tolower = expression.call(expression, typeof(string).getmethod("tolower", system.type.emptytypes)); var = expression.call(tolower, typeof(string).getmethod("contains"), expression.constant(filtertext.tolower())); //todo: combine expressions form single expression<func<t, bool>> expression } return predicate; } /// <summary> /// deeper properties such role.name expressions /// </summary> private static expression getdeeppropertyexpression(expression initialinstance, string property) { expression result = null; foreach (string propertyname in property.split('.')) { expression instance = result ?? initialinstance; result = expression.property(instance, propertyname); } return result; }
i have created few search iqueryable
extension methods should able use
full blog post here:
http://jnye.co/posts/6/c%23-generic-search-extension-method-for-iqueryable
github project here (has couple of extensions or
searches:
https://github.com/ninjanye/searchextensions
public static class queryableextensions { public static iqueryable<t> search<t>(this iqueryable<t> source, expression<func<t, string>> stringproperty, string searchterm) { if (string.isnullorempty(searchterm)) { return source; } // below represents following lamda: // source.where(x => x.[property] != null // && x.[property].contains(searchterm)) //create expression represent x.[property] != null var isnotnullexpression = expression.notequal(stringproperty.body, expression.constant(null)); //create expression represent x.[property].contains(searchterm) var searchtermexpression = expression.constant(searchterm); var checkcontainsexpression = expression.call(stringproperty.body, typeof(string).getmethod("contains"), searchtermexpression); //join not null , contains expressions var notnullandcontainsexpression = expression.andalso(isnotnullexpression, checkcontainsexpression); var methodcallexpression = expression.call(typeof(queryable), "where", new type[] { source.elementtype }, source.expression, expression.lambda<func<t, bool>>(notnullandcontainsexpression, stringproperty.parameters)); return source.provider.createquery<t>(methodcallexpression); } }
this allows write like:
string searchterm = "test"; var results = context.menu.search(menu => menu.menutext, searchterm).tolist(); //or role name string searchterm = "test"; var results = context.menu.search(menu => menu.role.name, searchterm).tolist();
you might find following posts useful:
search extension method allows search accros multiple properties:
http://jnye.co/posts/7/generic-iqueryable-or-search-on-multiple-properties-using-expression-trees
search extension method allows multiple or search terms on property:
http://jnye.co/posts/8/generic-iqueryable-or-search-for-multiple-search-terms-using-expression-trees
Comments
Post a Comment