c# - LINQ to Entities does not recognize the method 'Method name' method -
i'm having similar problem asked here: linq entities not recognize method 'system.string tostring()' method, , method cannot translated store expression
i'm trying paginate source, in case, can't put result of getpropertyvalue
in variable, because need x
that:
public ienumerable<tmodel> paginate(iqueryable<tmodel> source, ref int totalpages, int pageindex, int pagesize, string sortfield, sortdirection? sortdir) { totalpages = (int)math.ceiling(source.count() / (double)pagesize); if (sortdir == sortdirection.descending) { return source.orderbydescending(x => getpropertyvalue(x, sortfield)).skip(pageindex * pagesize).take(pagesize).tolist(); } else { return source.orderby(x => getpropertyvalue(x, sortfield)).skip(pageindex * pagesize).take(pagesize).tolist(); } } private static object getpropertyvalue(object obj, string name) { return obj == null ? null : obj.gettype().getproperty(name).getvalue(obj, null); }
what do, in case?
lambda expressions (those used within where, orderby etc) cannot contain c# specific code, can contain expression tree, translated sql. cannot call arbitrary methods there, except ones mentioned ef documentation such sqlfunctions etc.
in order sorting field name @ runtime, have create lambda expression @ runtime , pass on.
public ienumerable<tmodel> paginate(iqueryable<tmodel> source, ref int totalpages, int pageindex, int pagesize, string sortfield, sortdirection? sortdir) { totalpages = (int)math.ceiling(source.count() / (double)pagesize); if (sortdir == sortdirection.descending) { return source.orderbydescending(sortfield).skip(pageindex * pagesize).take(pagesize).tolist(); } else { return source.orderby(sortfield).skip(pageindex * pagesize).take(pagesize).tolist(); } } public static class queryablehelper { public static iqueryable<tmodel> orderby<tmodel>(this iqueryable<tmodel> q, string name) { type entitytype = typeof(tmodel); propertyinfo p = entitytype.getproperty(name); methodinfo m = typeof(queryablehelper).getmethod("orderbyproperty").makegenericmethod(entitytype, p.propertytype); return(iqueryable<tmodel>) m.invoke(null, new object[] { q, p }); } public static iqueryable<tmodel> orderbydescending<tmodel>(this iqueryable<tmodel> q, string name) { type entitytype = typeof(tmodel); propertyinfo p = entitytype.getproperty(name); methodinfo m = typeof(queryablehelper).getmethod("orderbypropertydescending").makegenericmethod(entitytype, p.propertytype); return (iqueryable<tmodel>)m.invoke(null, new object[] { q, p }); } public static iqueryable<tmodel> orderbypropertydescending<tmodel, tret>(iqueryable<tmodel> q, propertyinfo p) { parameterexpression pe = expression.parameter(typeof(tmodel)); expression se = expression.convert(expression.property(pe, p), typeof(object)); return q.orderbydescending(expression.lambda<func<tmodel, tret>>(se, pe)); } public static iqueryable<tmodel> orderbyproperty<tmodel, tret>(iqueryable<tmodel> q, propertyinfo p) { parameterexpression pe = expression.parameter(typeof(tmodel)); expression se = expression.convert(expression.property(pe, p), typeof(object)); return q.orderby(expression.lambda<func<tmodel, tret>>(se, pe)); } }
this solution works on single level of property, if want nested levels needs more work, perhaps can @ following sdk of that.
however if take @ entity rest sdk itself, has many things , things might need. disclaimer: author.
Comments
Post a Comment