我在VS2008动态LINQ示例中找到了一个示例,允许您使用类似sql的字符串(例如OrderBy(“Name, Age DESC”))进行排序。不幸的是,所包含的方法只适用于IQueryable<T>。有什么办法得到这个功能IEnumerable<T>?
当前回答
我还发现了一些有趣的东西。 如果你的数据源是一个数据表,你可以使用动态排序而不使用动态Linq
DataTable orders = dataSet.Tables["SalesOrderHeader"];
EnumerableRowCollection<DataRow> query = from order in orders.AsEnumerable()
orderby order.Field<DateTime>("OrderDate")
select order;
DataView view = query.AsDataView();
bindingSource1.DataSource = view;
参考:http://msdn.microsoft.com/en-us/library/bb669083.aspx(使用DataSetExtensions)
下面是另一种将其转换为DataView的方法:
DataTable contacts = dataSet.Tables["Contact"];
DataView view = contacts.AsDataView();
view.Sort = "LastName desc, FirstName asc";
bindingSource1.DataSource = view;
dataGridView1.AutoResizeColumns();
其他回答
我想使用反射来获得你想要排序的任何属性是可行的:
IEnumerable<T> myEnumerables
var query=from enumerable in myenumerables
where some criteria
orderby GetPropertyValue(enumerable,"SomeProperty")
select enumerable
private static object GetPropertyValue(object obj, string property)
{
System.Reflection.PropertyInfo propertyInfo=obj.GetType().GetProperty(property);
return propertyInfo.GetValue(obj, null);
}
注意,使用反射比直接访问属性要慢得多,因此必须研究性能。
我试图这样做,但有问题与Kjetil Watnedal的解决方案,因为我不使用内联linq语法-我更喜欢方法风格的语法。我的具体问题是尝试使用自定义IComparer进行动态排序。
我的解决方案是这样的:
给定一个IQueryable查询,如下:
List<DATA__Security__Team> teams = TeamManager.GetTeams();
var query = teams.Where(team => team.ID < 10).AsQueryable();
给定一个运行时排序字段参数:
string SortField; // Set at run-time to "Name"
动态OrderBy看起来是这样的:
query = query.OrderBy(item => item.GetReflectedPropertyValue(SortField));
这是使用一个叫做GetReflectedPropertyValue()的小助手方法:
public static string GetReflectedPropertyValue(this object subject, string field)
{
object reflectedValue = subject.GetType().GetProperty(field).GetValue(subject, null);
return reflectedValue != null ? reflectedValue.ToString() : "";
}
最后一件事——我提到过我想让OrderBy使用自定义iccomparer——因为我想做自然排序。
要做到这一点,我只需要改变OrderBy为:
query = query.OrderBy(item => item.GetReflectedPropertyValue(SortField), new NaturalSortComparer<string>());
有关NaturalSortComparer()的代码,请参阅这篇文章。
你可以用这个:
public List<Book> Books(string orderField, bool desc, int skip, int take)
{
var propertyInfo = typeof(Book).GetProperty(orderField);
return _context.Books
.Where(...)
.OrderBy(p => !desc ? propertyInfo.GetValue(p, null) : 0)
.ThenByDescending(p => desc ? propertyInfo.GetValue(p, null) : 0)
.Skip(skip)
.Take(take)
.ToList();
}
这个答案是对@John Sheehan - Runscope提供的解决方案需要一个示例的评论的回应
请为我们其他人提供一个例子。
在DAL(数据访问层),
IEnumerable版本:
public IEnumerable<Order> GetOrders()
{
// i use Dapper to return IEnumerable<T> using Query<T>
//.. do stuff
return orders // IEnumerable<Order>
}
IQueryable版本
public IQueryable<Order> GetOrdersAsQuerable()
{
IEnumerable<Order> qry= GetOrders();
// use the built-in extension method AsQueryable in System.Linq namespace
return qry.AsQueryable();
}
现在你可以使用IQueryable版本来绑定,例如Asp.net中的GridView和排序的好处(你不能使用IEnumerable版本进行排序)
我使用Dapper作为ORM并构建IQueryable版本,并在asp.net中的GridView中使用排序。
var result1 = lst.OrderBy(a=>a.Name);// for ascending order.
var result1 = lst.OrderByDescending(a=>a.Name);// for desc order.
推荐文章
- Linq-to-Entities Join vs GroupJoin
- 为什么字符串类型的默认值是null而不是空字符串?
- 在list中获取不同值的列表
- 组合框:向项目添加文本和值(无绑定源)
- 如何为ASP.net/C#应用程序配置文件值中的值添加&号
- 从System.Drawing.Bitmap中加载WPF BitmapImage
- 如何找出一个文件存在于c# / .NET?
- 为什么更快地检查字典是否包含键,而不是捕捉异常,以防它不?
- [DataContract]的命名空间
- string. isnullorempty (string) vs. string. isnullowhitespace (string)
- 完全外部连接
- 在foreach循环中编辑字典值
- 如何在xml文档中引用泛型类和方法
- 使用System.IO.Compression在内存中创建ZIP存档
- 从HttpResponseMessage获取内容/消息