ASP.Net 4.5模型绑定按导航属性排序

所有,

我有一个网格视图,其中包含以下列。 分页工作很棒,但没有排序。 每次我点击Category列按类别排序我都会收到此错误:

没有为类型’ESA.Data.Models.Entity.Project’定义实例属性’Category.CategoryName’

此错误声明不正确,因为gridview能够正确显示列。

这是select方法

public IQueryable getProjects() { ApplicationServices objServices = new ApplicationServices(); IQueryable lstProject; lstProject = objServices.getProjects(); return lstProject; } 

有什么建议吗?

            

我在使用Listview控件时遇到了类似的问题。 我这样解决了。

首先我使用的是Marc Gravell 动态LINQ OrderBy在IEnumerable 上的post中的代码

在我的Listview的’OnSorting’事件中,我添加了以下代码。

 protected void lv_Sorting(object sender, ListViewSortEventArgs e) { e.Cancel = true; ViewState["OrderBy"] = e.SortExpression; lvList.DataBind(); } 

我添加了一种相当标准的方法来捕获sortdirection列表

 public SortDirection sortDirection { get { 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; } } 

在我的Listview中,Selectmethod看起来像这样(使用Marc的扩展方法)

 public IQueryable 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; } 

我没有尝试使用GridView但我相当肯定它会起作用。

编辑这是一个应该工作的linq扩展类的例子

 public static class LinqExtensions { public static IOrderedQueryable OrderBy(this IQueryable source, string property) { return ApplyOrder(source, property, "OrderBy"); } public static IOrderedQueryable OrderByDescending(this IQueryable source, string property) { return ApplyOrder(source, property, "OrderByDescending"); } public static IOrderedQueryable ThenBy(this IOrderedQueryable source, string property) { return ApplyOrder(source, property, "ThenBy"); } public static IOrderedQueryable ThenByDescending(this IOrderedQueryable source, string property) { return ApplyOrder(source, property, "ThenByDescending"); } static IOrderedQueryable ApplyOrder(IQueryable 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) to 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)result; } } 

只需在页面上添加一个使用’whatevernamespaceyouused’,你应该很高兴。

将名为sortByExpression的字符串参数添加到getProjects()方法中。

如果gridView在您的方法签名中找到此参数,它将不会尝试“自动命令”您的结果,它将让您完成工作。

要自己完成这项工作,可以使用DynamicLinq (您可以添加nuget包 ,或使用LinqExtensions 发布的LinqExtensions类)。

所以你的方法看起来像这样:

 // using System.Linq.Dynamic; public IQueryable getProjects(string sortByExpression) { ApplicationServices objServices = new ApplicationServices(); IQueryable lstProject = objServices.getProjects(); if (!String.IsNullOrEmpty(sortByExpression)) lstProject = lstProject.OrderBy(sortByExpression); return lstProject; } 

这样您就不会绕过gridView排序样式。

来源:反编译的框架代码,特别是 System.Web.UI.WebControls.ModelDataSourceView.IsAutoSortingRequired(...)

Drauka你的解决方案适合我,但是我会在这行代码中得到一个错误,尽管我已经引用了System.Linq.Dynamic

给我语法错误的两行是

lstProject = lstProject.OrderByDescending(OrderBy);

和错误消息是

无法从用法中推断出方法’System.Linq.Enumerable.OrderByDescending(System.Collections.Generic.IEnumerable,System.Func)’的类型参数。 尝试显式指定类型参数。

  public IQueryable getProjects([ViewState("OrderBy")]String OrderBy = null) { ApplicationServices objServices = new ApplicationServices(); var lstProject = objServices.getProjects(); if (OrderBy != null) { switch (sortDirection) { case SortDirection.Ascending: lstProject = lstProject.OrderByDescending(OrderBy); break; case SortDirection.Descending: lstProject = lstProject.OrderBy(OrderBy); break; default: lstProject = lstProject.OrderByDescending(OrderBy); break; } } return lstProject; }