c# - Predicate Builder for dynamic Objects -


i have home made library creates expresions used in filetring data in grids ui elemen basic method:

public static expression<func<t, bool>> getpredicate<t>( string modelpropertyname, searchtype searchtype, object data)  

it's simple query objects. basicaly need property name, operator , data compare. it's using reflection create expressions each operator.

and have requirement extend functionality.... method uses type t can see.now want me change , pass type argument new method should like:

public static expression<func<object, bool>> getpredicate(type t , string modelpropertyname, searchtype searchtype, object data)  

the don't know how many propperties object have. want tu use "dynamic" objects , expandoobjects. sucks.

i don't know if can anonymous type @ runtime expandobject. don't know if can return

expression<func<object, bool>> 

and apply expression dynamic object. sure can't used within linq sql, within linq objects it's hard accomplish.

in fact they(devs team btw) considering using dictionaries.

could point me maybe library can this? or maybe way shodl start this?

this entire class ( usefull btw)

namespace ########################### {     using system;     using system.collections;     using system.collections.generic;     using system.linq;     using system.linq.expressions;     using system.reflection;     using system.text;     using system.threading.tasks;      public static class predicatebuilder     {         #region public  static methods          /// <summary>         ///  main method of class returns predicate         ///           /// </summary>         /// <typeparam name="t">entity type - search where</typeparam>         /// <param name="modelpropertyname">property compare (compare what)(can nested property)</param>         /// <param name="searchtype">comparation type (compare how)</param>         /// <param name="data">data compare (compare )</param>         /// <returns>able translate sql predicate</returns>         public static expression<func<t, bool>> getpredicate<t>(string modelpropertyname, searchtype searchtype, object data) t : class         {             parameterexpression parameterexp = expression.parameter(typeof(t), "t");             memberexpression member = expression.propertyorfield(parameterexp, modelpropertyname.split('.').first());              // if there dots in parram have change expression              foreach (var innermember in modelpropertyname.split('.').skip(1))             {                 member = expression.propertyorfield(member, innermember);             }              if (member.type.basetype.tostring() == "system.enum")             {                 data = int32.parse(data.tostring());                 string name = enum.getname(member.type, data);                 data = enum.parse(member.type, name, false);             }             else if (searchtype != searchtype.isin)             {                 switch (member.type.tostring())                 {                     case "system.nullable`1[system.int32]":                         data = data.tostring().tonullableint32();                         break;                      case "system.nullable`1[system.boolean]":                         data = data.tostring().tonullableboolean();                         break;                      case "system.boolean":                         data = boolean.parse(data.tostring());                         break;                      case "system.nullable`1[system.datetime]":                         data = data.tostring().tonullabledatetime();                         break;                      case "system.datetime":                         data = datetime.parse(data.tostring());                         break;                      case "system.int32":                         data = int32.parse(data.tostring());                         break;                 }             }             constantexpression valuetocheck;              if (searchtype == searchtype.isin)             {                 valuetocheck = expression.constant(data, getlisttype(member.type));             }             else             {                 valuetocheck = expression.constant(data, member.type);             }              expression expression = getexpression<t>(searchtype, member, valuetocheck);              expression<func<t, bool>> predicate = expression.lambda<func<t, bool>>(expression, new parameterexpression[] { parameterexp });             return predicate;         }          private static expression getexpression<t>(searchtype searchtype, memberexpression member, constantexpression valuetocheck) t : class         {             expression expression;             switch (searchtype)             {                 case searchtype.equal:                     expression = equals<t>(member, valuetocheck);                     break;                  case searchtype.notequal:                     expression = notequals<t>(member, valuetocheck);                     break;                  case searchtype.less:                     expression = less<t>(member, valuetocheck);                     break;                  case searchtype.lessorequal:                     expression = lessorequal<t>(member, valuetocheck);                     break;                  case searchtype.greater:                     expression = more<t>(member, valuetocheck);                     break;                  case searchtype.greaterorequal:                     expression = moreorequal<t>(member, valuetocheck);                     break;                  case searchtype.beginswith:                     expression = beginswith<t>(member, valuetocheck);                     break;                  case searchtype.doesnotbeginwith:                     expression = notbeginswith<t>(member, valuetocheck);                     break;                  case searchtype.isin:                     expression = isin<t>(member, valuetocheck);                     break;                  case searchtype.isnotin:                     expression = notcontains<t>(member, valuetocheck);                     break;                  case searchtype.endswith:                     expression = endswith<t>(member, valuetocheck);                     break;                  case searchtype.doesnotendwith:                     expression = notendswith<t>(member, valuetocheck);                     break;                  case searchtype.contains:                     expression = contains<t>(member, valuetocheck);                     break;                  case searchtype.doesnotcontain:                     expression = notcontains<t>(member, valuetocheck);                     break;                  case searchtype.isnull:                     expression = isnull<t>(member, valuetocheck);                     break;                  case searchtype.isnotnull:                     expression = isnotnull<t>(member, valuetocheck);                     break;                  default:                     expression = expression<func<t, bool>>.equal(member, valuetocheck);                     break;             }             return expression;         }          public static expression<func<t, bool>> and<t>(this expression<func<t, bool>> expr1,                                                              expression<func<t, bool>> expr2)         {             var invokedexpr = expression.invoke(expr2, expr1.parameters.cast<expression>());             return expression.lambda<func<t, bool>>                   (expression.andalso(expr1.body, invokedexpr), expr1.parameters);         }          public static expression<func<t, bool>> or<t>(this expression<func<t, bool>> expr1,                                                             expression<func<t, bool>> expr2)         {             var invokedexpr = expression.invoke(expr2, expr1.parameters.cast<expression>());             return expression.lambda<func<t, bool>>                   (expression.orelse(expr1.body, invokedexpr), expr1.parameters);         }          public static expression<func<t, bool>> false<t>()         {             return f => false;         }          public static expression<func<t, bool>> true<t>()         {             return f => true;         }          public static ilist createlist(type type)         {             type genericlisttype = typeof(list<>).makegenerictype(type);             return ((ilist)activator.createinstance(genericlisttype));         }          public static type getlisttype(type type)         {             return createlist(type).gettype();         }          #endregion public  static methods          #region predicateexpressions          private static expression beginswith<t>(memberexpression member, constantexpression valuetocheck)         {             methodinfo method = typeof(string).getmethod("startswith", new[] { typeof(string) });             return expression<func<t, bool>>.call(member, method, valuetocheck);         }          private static expression contains<t>(memberexpression member, constantexpression valuetocheck)         {              methodinfo method = typeof(string).getmethod("contains", new[] { typeof(string) });             return expression<func<t, bool>>.call(member, method, valuetocheck);         }          private static expression isin<t>(memberexpression member, constantexpression valuetocheck)         {             methodinfo method = getlisttype(member.type).getmethod("contains", new[] { member.type });              return expression<func<t, bool>>.call(valuetocheck, method, member);         }          private static expression endswith<t>(memberexpression member, constantexpression valuetocheck)         {             methodinfo method = typeof(string).getmethod("endswith", new[] { typeof(string) });             return expression<func<t, bool>>.call(member, method, valuetocheck);         }          private static expression equals<t>(memberexpression member, constantexpression valuetocheck)         {             return expression<func<t, bool>>.equal(member, valuetocheck);         }          private static expression isnotnull<t>(memberexpression member, constantexpression valuetocheck)         {             return expression<func<t, bool>>.notequal(member, expression.constant(null, member.type));         }          private static expression isnull<t>(memberexpression member, constantexpression valuetocheck)         {             return expression<func<t, bool>>.equal(member, expression.constant(null, member.type));         }          private static expression less<t>(memberexpression member, constantexpression valuetocheck)         {             return expression<func<t, bool>>.lessthan(member, valuetocheck);         }          private static expression lessorequal<t>(memberexpression member, constantexpression valuetocheck)         {             return expression<func<t, bool>>.lessthanorequal(member, valuetocheck);         }          private static expression more<t>(memberexpression member, constantexpression valuetocheck)         {             return expression<func<t, bool>>.greaterthan(member, valuetocheck);         }          private static expression moreorequal<t>(memberexpression member, constantexpression valuetocheck)         {             return expression<func<t, bool>>.greaterthanorequal(member, valuetocheck);         }          private static expression notbeginswith<t>(memberexpression member, constantexpression valuetocheck)         {             methodinfo method = typeof(string).getmethod("startswith", new[] { typeof(string) });             return expression.not(expression<func<t, bool>>.call(member, method, valuetocheck));         }          private static expression notcontains<t>(memberexpression member, constantexpression valuetocheck)         {             methodinfo method = typeof(string).getmethod("contains", new[] { typeof(string) });             return expression.not(expression<func<t, bool>>.call(member, method, valuetocheck));         }          private static expression notendswith<t>(memberexpression member, constantexpression valuetocheck)         {             methodinfo method = typeof(string).getmethod("endswith", new[] { typeof(string) });             return expression.not(expression<func<t, bool>>.call(member, method, valuetocheck));         }          private static expression notequals<t>(memberexpression member, constantexpression valuetocheck)         {             return expression<func<t, bool>>.notequal(member, valuetocheck);         }          #endregion predicateexpressions          #region pivate static         private static boolean? tonullableboolean(this string s)         {             bool i;             if (boolean.tryparse(s, out i)) return i;             return null;         }          private static datetime? tonullabledatetime(this string s)         {             datetime i;             if (datetime.tryparse(s, out i)) return i;             return null;         }          private static int? tonullableint32(this string s)         {             int i;             if (int32.tryparse(s, out i)) return i;             return null;         }         #endregion     } } 


Comments

Popular posts from this blog

How has firefox/gecko HTML+CSS rendering changed in version 38? -

javascript - Complex json ng-repeat -

jquery - Cloning of rows and columns from the old table into the new with colSpan and rowSpan -