请考虑以下情况:
我有一个类的大约有50 fields.I名单希望有一个组合框用户可以根据什么字段列表将sort.For例如,如果用户排序按“F1”选择“F1”列表中选择。
我不想用排序if-else
为每fields.I看到这个话题:
数据绑定对象的集合或列表排序时,一个gridview
但我不能用它的答案。 如何使用Expression Tree
为了这个目的?
谢谢
编辑1):
据亲爱@Thom史密斯回答我写这样的代码:
using (NorthwindModel1.NorthwindEntities2 ent = new NorthwindModel1.NorthwindEntities2())
{
var query = from o in ent.Orders
where o.OrderID < 10257
select o;
query.OrderBy("CustomerID", SortDirection.Ascending);
GridView1.DataSource = query;
GridView1.DataBind();
}
但它没有排序。 如果我写的代码是这样的:
GridView1.DataSource = query.OrderBy(o=>o.CustomerID);
它是排序。 问题出在哪儿?
排序依据不做就地排序。 它返回 评估进行排序时的顺序。 这通常是懒洋洋的,意思是:直到它被枚举,它什么都不做 。 您当前的代码简单地丢弃这件十分重要的返回值。 解决方法是简单的:赶返回值:
query = query.OrderBy("CustomerID", SortDirection.Ascending);
注:同样,将“去哪儿”不过滤现有数据:它返回一个序列列举时被过滤。 所以,如果你是过滤你有类似的:
query = query.Where(...);
下面是我用这个方法:
private IQueryable<T> OrderQuery<T>(IQueryable<T> query, OrderParameter orderBy)
{
string orderMethodName = orderBy.Direction == SortDirection.Ascending ? "OrderBy" : "OrderByDescending";
Type t = typeof(T);
var param = Expression.Parameter(t, "shipment");
var property = t.GetProperty(orderBy.Attribute);
/* We can't just call OrderBy[Descending] with an Expression
* parameter because the second type argument to OrderBy is not
* known at compile-time.
*/
return query.Provider.CreateQuery<T>(
Expression.Call(
typeof(Queryable),
orderMethodName,
new Type[] { t, property.PropertyType },
query.Expression,
Expression.Quote(
Expression.Lambda(
Expression.Property(param, property),
param))
));
}
OrderParameter
仅仅是一个与属性和方向结构。
编辑:附加说明。
这种方法是从我DynamicOrderList
类,它是名单OrderParameter
对象。 如果你需要的是一个字段排序,那么你可以把它简化一下:
private IQueryable<T> OrderByDynamic<T>(this IQueryable<T> query, string attribute, SortDirection direction)
{
try
{
string orderMethodName = direction == SortDirection.Ascending ? "OrderBy" : "OrderByDescending";
Type t = typeof(T);
var param = Expression.Parameter(t);
var property = t.GetProperty(attribute);
return query.Provider.CreateQuery<T>(
Expression.Call(
typeof(Queryable),
orderMethodName,
new Type[] { t, property.PropertyType },
query.Expression,
Expression.Quote(
Expression.Lambda(
Expression.Property(param, property),
param))
));
}
catch (Exception) // Probably invalid input, you can catch specifics if you want
{
return query; // Return unsorted query
}
}
然后使用它像:
myQuery = myQuery.OrderByDynamic("name", SortDirection.Ascending);
编辑2:
public IQueryable<T> OrderBy<T>(this IQueryable<T> query, string attribute, SortDirection direction)
{
return ApplyOrdering(query, attribute, direction, "OrderBy");
}
public IQueryable<T> ThenBy<T>(this IQueryable<T> query, string attribute, SortDirection direction)
{
return ApplyOrdering(query, attribute, direction, "ThenBy");
}
private IQueryable<T> ApplyOrdering<T>(IQueryable<T> query, string attribute, SortDirection direction, string orderMethodName)
{
try
{
if (direction == SortDirection.Descending) orderMethodName += "Descending";
Type t = typeof(T);
var param = Expression.Parameter(t);
var property = t.GetProperty(attribute);
return query.Provider.CreateQuery<T>(
Expression.Call(
typeof(Queryable),
orderMethodName,
new Type[] { t, property.PropertyType },
query.Expression,
Expression.Quote(
Expression.Lambda(
Expression.Property(param, property),
param))
));
}
catch (Exception) // Probably invalid input, you can catch specifics if you want
{
return query; // Return unsorted query
}
}
和:
myQuery=myQuery.OrderBy("name", SortDirection.Ascending).ThenBy("date", SortDirection.Descending);
这里是我的温热服食,使用Enumerable
+反思,而不是查询:
list.OrderBy(x => {
var prop = x.GetType().GetProperty(sortFieldName);
return prop.GetValue(x);
});
if (!isSortAsc) list.Reverse();
希望这会有所帮助。 它为我工作来过滤C#列表,动态
string jtSorting = "ContactName";
DashboardModel Sup = new DashboardModel();
List<Applicant> lstSup = Sup.GetonBoard();
lstSup = lstSup.AsQueryable().SortBy(jtSorting).ToList();