c# - ASP.Net 4.5 Model Binding Sorting By Navigation Property -
all,
i have grid view has following columns. paging work great, not sorting. everytime click on category column sort category error:
instance property 'category.categoryname' not defined type 'esa.data.models.entity.project'
this error statement not true because gridview able display column correctly.
here select method
public iqueryable<project> getprojects() { applicationservices objservices = new applicationservices(); iqueryable<project> lstproject; lstproject = objservices.getprojects(); return lstproject; }
any suggestion?
<asp:gridview id="grdproject" runat="server" showheader="true" autogeneratecolumns="false" cellpadding="2" cellspacing="2" itemtype="esa.data.models.entity.project" selectmethod="getprojects" datakeynames="projectid" allowsorting="true" allowpaging="true" pagesize="5"> <columns> <asp:boundfield datafield="projectid" headertext="id " itemstyle-width="10" /> <asp:boundfield datafield="category.categoryname" headertext="category" sortexpression="category.categoryname" /> <asp:boundfield datafield="projectname" headertext="project name" itemstyle-width="300" /> <asp:boundfield datafield="status.statusname" headertext="status" sortexpression="status.statusname" /> <asp:boundfield datafield="addedbyuser.username" headertext="added by" itemstyle-width="120" /> <asp:boundfield datafield="addeddate" headertext="added date" itemstyle-width="90" dataformatstring="{0:d}" /> </columns> </asp:gridview>
i having similar issue listview control. solved this.
firstly i'm using code post marc gravell dynamic linq orderby on ienumerable<t>
in listview's 'onsorting' event added following code.
protected void lv_sorting(object sender, listviewsorteventargs e) { e.cancel = true; viewstate["orderby"] = e.sortexpression; lvlist.databind(); }
i added standard way capture sortdirection list
public sortdirection sortdirection { { if (viewstate["sortdirection"] == null) { viewstate["sortdirection"] = sortdirection.ascending; return sortdirection.ascending; } else if ((sortdirection)viewstate["sortdirection"] == sortdirection.ascending) { viewstate["sortdirection"] = sortdirection.descending; return sortdirection.descending; } else { viewstate["sortdirection"] = sortdirection.ascending; return sortdirection.ascending; } } set { viewstate["sortdirection"] = value; } }
in listview selectmethod looks (using extension method marc)
public iqueryable<someobject> getobjects([viewstate("orderby")]string orderby = null) { var list = getsomeobjects(); if (orderby != null) { switch (sortdirection) { case sortdirection.ascending: list = list.orderbydescending(orderby); break; case sortdirection.descending: list = list.orderby(orderby); break; default: list = list.orderbydescending(orderby); break; } } return list; }
i haven't tried gridview i'm work same.
edit here example of linq extension class should work
public static class linqextensions { public static iorderedqueryable<t> orderby<t>(this iqueryable<t> source, string property) { return applyorder<t>(source, property, "orderby"); } public static iorderedqueryable<t> orderbydescending<t>(this iqueryable<t> source, string property) { return applyorder<t>(source, property, "orderbydescending"); } public static iorderedqueryable<t> thenby<t>(this iorderedqueryable<t> source, string property) { return applyorder<t>(source, property, "thenby"); } public static iorderedqueryable<t> thenbydescending<t>(this iorderedqueryable<t> source, string property) { return applyorder<t>(source, property, "thenbydescending"); } static iorderedqueryable<t> applyorder<t>(iqueryable<t> source, string property, string methodname) { string[] props = property.split('.'); type type = typeof(t); parameterexpression arg = expression.parameter(type, "x"); expression expr = arg; foreach (string prop in props) { // use reflection (not componentmodel) mirror linq propertyinfo pi = type.getproperty(prop); expr = expression.property(expr, pi); type = pi.propertytype; } type delegatetype = typeof(func<,>).makegenerictype(typeof(t), type); lambdaexpression lambda = expression.lambda(delegatetype, expr, arg); object 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; } }
simply add using 'whatevernamespaceyouused' page , should go.
Comments
Post a Comment