C# ASP.Net 4.5模型绑定按导航属性排序
全部, 我有一个网格视图,其中包含以下列。分页工作很好,但排序不好。每次单击“类别”列按类别排序时,我都会出现以下错误: 未为类型“ESA.Data.Models.Entity.Project”定义实例属性“Category.CategoryName” 此错误语句不正确,因为gridview能够正确显示列 下面是选择方法C# ASP.Net 4.5模型绑定按导航属性排序,c#,asp.net,model-binding,C#,Asp.net,Model Binding,全部, 我有一个网格视图,其中包含以下列。分页工作很好,但排序不好。每次单击“类别”列按类别排序时,我都会出现以下错误: 未为类型“ESA.Data.Models.Entity.Project”定义实例属性“Category.CategoryName” 此错误语句不正确,因为gridview能够正确显示列 下面是选择方法 public IQueryable<Project> getProjects() { ApplicationServices obj
public IQueryable<Project> getProjects()
{
ApplicationServices objServices = new ApplicationServices();
IQueryable<Project> lstProject;
lstProject = objServices.getProjects();
return lstProject;
}
public IQueryable getProjects()
{
ApplicationServices objServices=新的ApplicationServices();
IQueryable项目;
lstProject=objServices.getProjects();
返回项目;
}
有什么建议吗
<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>
我在Listview控件上遇到了类似的问题。 我是这样解决的 首先,我使用了Marc Gravell的这篇文章中的代码 在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)
{
开关(排序方向)
{
案例排序方向。升序:
list=list.OrderByDescending(OrderBy);
打破
案例排序方向。下行:
list=list.OrderBy(OrderBy);
打破
违约:
list=list.OrderByDescending(OrderBy);
打破
}
}
退货清单;
}
我还没有用GridView尝试过,但我相当肯定它也能正常工作
编辑
下面是一个应该可以工作的linq扩展类的示例
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) 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<T>)result;
}
}
公共静态类LinqExtensions
{
公共静态IOrderedQueryable OrderBy(此IQueryable源,字符串属性)
{
返回ApplyOrder(来源、属性、“订购者”);
}
公共静态IOrderedQueryable OrderByDescending(此IQueryable源,字符串属性)
{
返回ApplyOrder(源,属性,“OrderByDescending”);
}
公共静态IOrderedQueryable ThenBy(此IOrderedQueryable源,字符串属性)
{
返回申请者(来源、财产,“ThenBy”);
}
公共静态IOrderedQueryable然后按降序(此IOrderedQueryable源,字符串属性)
{
返回ApplyOrder(源、属性,“然后按降序”);
}
静态IOrderedQueryable ApplyOrder(IQueryable源、字符串属性、字符串方法名)
{
字符串[]props=property.Split('.');
类型=类型(T);
ParameterExpression arg=Expression.Parameter(类型为“x”);
表达式expr=arg;
foreach(道具中的字符串道具)
{
//使用反射(非组件模型)镜像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);
对象结果=typeof(Queryable).GetMethods().Single(
method=>method.Name==methodName
&&方法.IsGenericMethodDefinition
&&方法。GetGenericArguments()。长度==2
&&方法。GetParameters().Length==2)
.MakeGenericMethod(typeof(T),type)
.Invoke(null,新对象[]{source,lambda});
返回(IOrderedQueryable)结果;
}
}
只需在页面中添加一个使用“WhateVernamespace youused”的选项,您就可以开始了。Drauka您的解决方案对我很有效,但即使我已经参考了System.Linq.Dynamic,我也会在这行代码中出错 给出语法错误的两行是 lstProject=lstProject.OrderByDescending(OrderBy) 错误消息是 无法从用法推断方法“System.Linq.Enumerable.OrderByDescending(System.Collections.Generic.IEnumerable,System.Func)”的类型参数。尝试显式指定类型参数
public IQueryable<Project> 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;
}
public IQueryable getProjects([ViewState(“OrderBy”)]String OrderBy=null)
{
ApplicationServices objServices=新的ApplicationServices();
var lstProject=objServices.getProjects();
if(OrderBy!=null)
{
开关(排序方向)
{
案例排序方向。升序:
lstProject=lstProject.OrderByDescending(OrderBy);
打破
案例排序方向。下行:
lstProject=lstProject.OrderBy(OrderBy);
打破
违约:
lstProject=lstProject.OrderByDescending(OrderBy);
打破
}
}
返回项目;
}
将名为sortByExpression
的字符串参数添加到getProjects()
方法中
如果gridView在你的方法签名中找到这个参数,它不会尝试“自动排序”你的结果,它会让你完成这项工作
要自己完成这项工作,您可以使用(您可以添加或使用LinqExtensions
类)
因此,您的方法如下所示:
// using System.Linq.Dynamic;
public IQueryable<Project> getProjects(string sortByExpression)
{
ApplicationServices objServices = new ApplicationServices();
IQueryable<Project> lstProject = objServices.getProjects();
if (!String.IsNullOrEmpty(sortByExpression))
lstProject = lstProject.OrderBy(sortByExpression);
return lstProject;
}
//使用System.Linq.Dynamic;
公共IQueryable GetProject(字符串sortByExpression)
{
ApplicationServices objServices=新的ApplicationServices();
IQueryable lstProject=objServices.getProjects();
如果(!String.IsNullOrEmpty(sortByExpression))
lstProject=lstProject.OrderBy(sortByExpression);
返回项目
// using System.Linq.Dynamic;
public IQueryable<Project> getProjects(string sortByExpression)
{
ApplicationServices objServices = new ApplicationServices();
IQueryable<Project> lstProject = objServices.getProjects();
if (!String.IsNullOrEmpty(sortByExpression))
lstProject = lstProject.OrderBy(sortByExpression);
return lstProject;
}