【问题标题】:Linq To SQL: Sort Query by Arbitrary Property(Column) NameLinq To SQL:按任意属性(列)名称对查询进行排序
【发布时间】:2013-03-13 14:32:58
【问题描述】:

我有一个更大/更复杂的问题,但为了简单起见,让我们考虑以下问题:

假设我在 SQL 数据库 中有一个名为 Product 的表,有两列 ID (int, primary key)名称 (varchar/string)。我还有一个简单的 LINQ DataContext

我有一个查询被构造并交给“我的”函数。让我们说它是这样的:(虽然它可能有点复杂)

IQueryable<Product> query = from p in db.Products select p;

一旦我的方法得到这个查询,作为参数传入,它必须改变排序顺序,例如

IQueryable<Product> sortedQuery = query.OrderBy(x => x.Name);

我想让它更通用,即指定要排序的字段。通常,我可以做一个带字符串的switch 语句。但是我想知道是否有办法直接传递参数。我打算将此扩展到其他数据库表,因此这些 switch 语句会变得乏味。

我正在尝试类似:

IQueryable<Product> sortedQuery = query.OrderBy(x => (typeof(Product)).GetProperty(“Name”));

但这不起作用。我还想确保维护 LINQ to SQL,即在 SQL Server 上进行的排序。因此,如果我调试,我应该从这个 LINQ 查询中得到一个 SQL 查询。

提前感谢您的帮助。

【问题讨论】:

  • 感谢@Viper,我想我真的在这里寻找Dynamic LINQ。使用它,我只需拥有IQueryable&lt;Product&gt; sortedQuery = query.OrderBy("Name asc");,这就是我想要的。
  • 不用太兴奋并查看绿色勾号解决方案,您已经完美地描述了我的确切问题。我也在尝试与您类似的解决方案。对向下滚动感到兴奋!

标签: c# linq c#-4.0 linq-to-sql


【解决方案1】:

您可以为此使用Dynamic Linq

请看这里Dynamic LINQ (Part 1: Using the LINQ Dynamic Query Library)

然后你可以这样调用:

var query = DBContext.Users.Where( "Age > 3" ).OrderBy( "Name asc" );

【讨论】:

  • 谢谢蝰蛇。这正是我一直在寻找的。对于其他人,您需要安装 Nuget 包 System.Linq.Dynamic 并引用它来编译它。
【解决方案2】:

试试这个:

query.OrderBy(x => x.GetType().GetProperty(“Name”).GetValue(x, null));

你不能只是抢夺财产。您需要从该属性中获取值,因此调用GetValue

【讨论】:

  • 谢谢钢铁侠,但这对我不起作用。如果我稍后执行sortedQuery.Count(),我会得到InvalidOperationException Cannot order by type 'System.Object'
  • 我还想提一下,如果我转换结果,即sortedQuery.OrderBy(x =&gt; (Product)x.GetType().GetProperty(“Name”).GetValue(x, null));,我会收到相同的异常消息 Cannot order by type 'MyDataContext.Product'
  • 当然不能。 1)GetValue 返回的对象无论如何都不是 Product 类型。它只能转换为与属性相同的类型。 2) LINQ 不知道如何通过Product 订购。您必须根据原始类型订购。
  • 因为在这种情况下,这不是由 Product 对象本身排序的。它基于 name 进行排序,这是一个字符串原语。这是 LINQ 可以理解的顺序。
  • OrderBy(x =&gt; x.Name);Name 排序,这是一个字符串。要知道如何订购产品变得更加复杂。我相信您需要在您的 Product 类上实现 IComparable 以便按 OrderBy 排序,尽管我不是 100% 确定。
【解决方案3】:

这并不像看起来那么容易。 LINQ to SQL 引擎解析您传递给OrderBy 方法的表达式,以获取您所引用的属性的名称,然后使用此信息组成一个普通的SQL order by 子句。

我想也许它可以通过使用反射来完成,无论如何。也许您可以从this SO question 接受的答案中得到一些有用的东西。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-11-24
    • 2017-03-18
    • 2012-03-14
    • 1970-01-01
    相关资源
    最近更新 更多