IEnumerable 上的动态 LINQ OrderBy / IQueryable;
我在动态 LINQ 的 VS2008 Examples 中找到了一个示例,它允许您使用类似 SQL 的字符串(例如 OrderBy("Name, Age DESC"))
用于排序。不幸的是,该方法仅适用于 IQueryable
。有没有办法在 IEnumerable
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(24)
只是偶然发现了这个老东西......
要在没有动态 LINQ 库的情况下执行此操作,您只需要如下代码。这涵盖了最常见的场景,包括嵌套属性。
要使其与
IEnumerable
一起使用,您可以添加一些通过AsQueryable
进行的包装方法 - 但下面的代码是核心Expression
逻辑需要。编辑:如果你想将其与
dynamic
混合,它会变得更有趣 - 尽管请注意dynamic
仅适用于LINQ-to-Objects(ORM等的表达式树可以' t 真正代表动态
查询 -MemberExpression
不支持它)。但这里有一种使用 LINQ-to-Objects 来实现这一点的方法。请注意,选择Hashtable
是由于有利的锁定语义:Just stumbled into this oldie...
To do this without the dynamic LINQ library, you just need the code as below. This covers most common scenarios including nested properties.
To get it working with
IEnumerable<T>
you could add some wrapper methods that go viaAsQueryable
- but the code below is the coreExpression
logic needed.Edit: it gets more fun if you want to mix that with
dynamic
- although note thatdynamic
only applies to LINQ-to-Objects (expression-trees for ORMs etc can't really representdynamic
queries -MemberExpression
doesn't support it). But here's a way to do it with LINQ-to-Objects. Note that the choice ofHashtable
is due to favorable locking semantics:太简单了,没有任何复杂性:
using System.Linq.Dynamic;
。vehicles = cars.AsQueryable().OrderBy("Make ASC, Year DESC").ToList();
编辑:为了节省一些时间,系统.Linq.Dynamic.Core(System.Linq.Dynamic 已弃用)程序集不是框架的一部分,但可以从 nuget 安装: System.Linq.Dynamic.Core
Too easy without any complication:
using System.Linq.Dynamic;
at the top.vehicles = vehicles.AsQueryable().OrderBy("Make ASC, Year DESC").ToList();
Edit: to save some time, the System.Linq.Dynamic.Core (System.Linq.Dynamic is deprecated) assembly is not part of the framework, but can be installed from nuget: System.Linq.Dynamic.Core
刚刚偶然发现了这个问题。
使用上面的 Marc 的 ApplyOrder 实现,我拼凑了一个扩展方法来处理类似 SQL 的字符串:
详细信息可以在此处找到: http://aonnull.blogspot.com/2010/08/dynamic-sql-like-linq-orderby-extension.html
Just stumbled across this question.
Using Marc's ApplyOrder implementation from above, I slapped together an Extension method that handles SQL-like strings like:
Details can be found here: http://aonnull.blogspot.com/2010/08/dynamic-sql-like-linq-orderby-extension.html
我想使用反射来获取您想要排序的任何属性是可行的:
请注意,使用反射比直接访问属性要慢得多,因此必须研究性能。
I guess it would work to use reflection to get whatever property you want to sort on:
Note that using reflection is considerably slower than accessing the property directly, so the performance would have to be investigated.
只是建立在其他人所说的基础上。我发现下面的方法效果很好。
Just building on what others have said. I found that the following works quite well.
我试图这样做,但遇到 Kjetil Watnedal 的解决方案 的问题,因为我不使用内联 linq 语法 - 我更喜欢方法风格的语法。我的具体问题是尝试使用自定义
IComparer
进行动态排序。我的解决方案最终是这样的:
给定一个像这样的 IQueryable 查询:
并给定一个运行时排序字段参数:
动态 OrderBy 看起来像这样:
这使用了一个名为 GetReflectedPropertyValue() 的小辅助方法:
最后一件事 - 我提到过我希望
OrderBy
使用自定义IComparer
- 因为我想做 自然排序。为此,我只需将
OrderBy
更改为:请参阅 这篇文章。
I was trying to do this but having problems with Kjetil Watnedal's solution because I don't use the inline linq syntax - I prefer method-style syntax. My specific problem was in trying to do dynamic sorting using a custom
IComparer
.My solution ended up like this:
Given an IQueryable query like so:
And given a run-time sort field argument:
The dynamic OrderBy looks like so:
And that's using a little helper method called GetReflectedPropertyValue():
One last thing - I mentioned that I wanted the
OrderBy
to use customIComparer
- because I wanted to do Natural sorting.To do that, I just alter the
OrderBy
to:See this post for the code for
NaturalSortComparer()
.经过大量搜索后,这对我有用:
After a lot of searching this worked for me:
我在寻找 Linq multiple orderby 子句时偶然发现了这个问题
也许这就是作者想要的,
具体方法如下:
I've stumble this question looking for Linq multiple orderby clauses
and maybe this was what the author was looking for
Here's how to do that:
使用动态
linq
只需添加
using System.Linq.Dynamic;
并像这样使用它来排序所有列:
Use dynamic
linq
just add
using System.Linq.Dynamic;
And use it like this to order all your columns:
首次安装动态
工具 --> NuGet 包管理器 -->包管理器控制台
添加命名空间
using System.Linq.Dynamic;
现在您可以使用
OrderBy("Name, Age DESC")
First Install Dynamic
Tools --> NuGet Package Manager --> Package Manager Console
Add Namespace
using System.Linq.Dynamic;
Now you can use
OrderBy("Name, Age DESC")
您可以添加它:
GetPropertyValue
函数来自 Kjetil Watnedal 的回答问题是为什么?任何此类排序都会在运行时抛出异常,而不是编译时(如 D2VIANT 的答案)。
如果您正在处理 Linq to Sql 并且 orderby 是一个表达式树,那么无论如何它都会被转换为 SQL 来执行。
You could add it:
The
GetPropertyValue
function is from Kjetil Watnedal's answerThe issue would be why? Any such sort would throw exceptions at run-time, rather than compile time (like D2VIANT's answer).
If you're dealing with Linq to Sql and the orderby is an expression tree it will be converted into SQL for execution anyway.
这是我发现的其他有趣的事情。
如果您的源是 DataTable,则可以使用动态排序,而无需使用 Dynamic Linq
参考: http://msdn.microsoft.com/en-us/library/bb669083.aspx(使用 DataSetExtensions)
这是另一种方法,将其转换为 DataView:
Here's something else I found interesting.
If your source is a DataTable, you can use dynamic sorting without using Dynamic Linq
reference: http://msdn.microsoft.com/en-us/library/bb669083.aspx (Using DataSetExtensions)
Here is one more way to do it by converting it to a DataView:
您可以将 IEnumerable 转换为 IQueryable。
You can convert the IEnumerable to IQueryable.
你可以使用这个:
You can use this:
替代解决方案使用以下类/接口。它不是真正动态的,但它有效。
An alternate solution uses the following class/interface. It's not truly dynamic, but it works.
感谢 Maarten(在 LINQ 中使用 PropertyInfo 对象查询集合 )我得到了这个解决方案:
在我的例子中,我正在处理“ColumnHeaderMouseClick”(WindowsForm),所以刚刚找到按下的特定列及其相应的PropertyInfo:
OR
(确保您的列名称与对象属性匹配)
干杯
Thanks to Maarten (Query a collection using PropertyInfo object in LINQ) I got this solution:
In my case I was working on a "ColumnHeaderMouseClick" (WindowsForm) so just found the specific Column pressed and its correspondent PropertyInfo:
OR
(be sure to have your column Names matching the object Properties)
Cheers
此答案是对需要 @John Sheehan - Runscope 提供的解决方案示例的评论的回应
在DAL(数据访问层)中,
IEnumerable版本:
IQueryable版本
现在您可以使用IQueryable版本进行绑定,例如Asp.net中的GridView,并有利于排序(你不能使用 IEnumerable 版本进行排序)
我使用 Dapper 作为 ORM 并构建 IQueryable 版本,并在 asp.net 中的 GridView 中使用排序,非常简单。
This answer is a response to the comments that need an example for the solution provided by @John Sheehan - Runscope
in DAL (Data Access Layer),
The IEnumerable version:
The IQueryable version
Now you can use the IQueryable version to bind, for example GridView in Asp.net and benefit for sorting (you can't sort using IEnumerable version)
I used Dapper as ORM and build IQueryable version and utilized sorting in GridView in asp.net so easy.
您可以定义从字符串到 Func<> 的字典。像这样:
并像这样使用它:
在这种情况下,您可以按字符串动态排序。
You can define a dictionary from string to Func<> like this :
And use it like this :
In this case you can dynamically sort by string.
你可以这样对多个订单进行操作
you can do it like this for multiple order by
将 List 转换为 IEnumerable 或 Iquerable,使用 System.LINQ.Dynamic 命名空间添加,然后您可以将逗号分隔字符串中的属性名称提及到 OrderBy 方法,该方法默认来自 System.LINQ.Dynamic。
Convert List to IEnumerable or Iquerable, add using System.LINQ.Dynamic namespace, then u can mention the property names in comma seperated string to OrderBy Method which comes by default from System.LINQ.Dynamic.
我可以使用下面的代码来做到这一点。无需编写又长又复杂的代码。
I am able to do this with the code below. No need write long and complex code.
如果您使用规范(例如 Ardalis 规范)
If you are using Specification (such as Ardalis Specification)
使用 Net6 和 EF
With Net6 and EF