c# - Get dynamic OrderBy in LINQ -
this question has answer here:
- dynamically sorting linq 9 answers
i using datatables in quite few pages in asp.net mvc 3 site. use server side paging , want implement sorting based on column headers. datatables comes isortcol_0
int value of column clicked.
i did not approach query end like:
if(isortcol_0 == 0) { // query // oderby(x => x.carname) }
then repeated each column (plus else clause on each order descending). have changed approach , pass column name server.
i have come following:
expression<func<vw_car, string>> sortexpression1 = null; expression<func<vw_car, int>> sortexpression2 = null; switch(columntosort) { case "invoiceno": sortexpression1 = x => x.carno; break; case "clientnumber": sortexpression1 = x => x.forename; break; case "clientname": sortexpression1 = x => x.surname; break; default: sortexpression2 = x => x.age.value; break; } // start of query .orderbydir(sortdirection, sortexpression1 , sortexpression2)
now orderbydir
looks below:
public static iorderedqueryable<t> orderbydir<t>(this iqueryable<t> source, string dir, expression<func<t, string>> column1, expression<func<t, int>> column2) { if (column1 != null) { return dir == "asc" ? source.orderby(column1) : source.orderbydescending(column1); } if (column2 != null) { return dir == "asc" ? source.orderby(column2) : source.orderbydescending(column2); } return null; }
this works in sorts columns of type string
or int
. have column of datetime
want sort, need write sortexpression3
, add orderbydir
.
however don't implementation - had attempted write generic sort expression took object second parameter instead of string
, int
, datetime
, when had code in place, getting unable cast type 'system.datetime' type 'system.object'. linq entities supports casting entity data model primitive types.
any 1 ideas possible better approach this?
such extension should fits needs:
public static class linqextensions { public static iorderedqueryable<t> orderby<t>(this iqueryable<t> source, string property) { return applyorder(source, property, "orderby"); } public static iorderedqueryable<t> orderbydescending<t>(this iqueryable<t> source, string property) { return applyorder(source, property, "orderbydescending"); } private static iorderedqueryable<t> applyorder<t>(iqueryable<t> source, string property, string methodname) { var props = property.split('.'); var type = typeof(t); var arg = expression.parameter(type, "x"); expression expr = arg; foreach (var prop in props) { // use reflection (not componentmodel) mirror linq var pi = type.getproperty(prop); expr = expression.property(expr, pi); type = pi.propertytype; } var delegatetype = typeof(func<,>).makegenerictype(typeof(t), type); var lambda = expression.lambda(delegatetype, expr, arg); var result = typeof(queryable).getmethods().single( method => method.name == methodname && method.isgenericmethoddefinition && method.getgenericarguments().length == 2 && method.getparameters().length == 2) .makegenericmethod(typeof(t), type) .invoke(null, new object[] { source, lambda }); return (iorderedqueryable<t>)result; } }
invoke example:
query.orderby("age.value");
Comments
Post a Comment