Linq To SQL:按任意属性(列)名称对查询进行排序

15

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

假设我有一个名为Product的表格在SQL数据库中,有两列,ID(int,主键)Name(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,我想我真正需要的是 动态LINQ。使用它,我只需要写 IQueryable<Product> sortedQuery = query.OrderBy("Name asc"); 就能达到我想要的效果了。 - O.O.
不要过于激动并盯着绿色对勾解决方案看,你已经完美地描述了我的问题。我也尝试了类似于你的解决方案。很兴奋能够向下滚动! - Andy
3个回答

19

4
谢谢,Viper。这正是我想要的。对于其他人,您需要安装Nuget包“System.Linq.Dynamic”并引用它,以便使其编译。 - O.O.

13

可以尝试使用这个:

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

你不能仅仅获取属性,而需要获取该属性的值,因此需要调用GetValue


1
谢谢钢铁侠,但这对我没用。如果我稍后执行sortedQuery.Count(),我会得到一个InvalidOperationException无法按类型“System.Object”排序 - O.O.
当然不行。1) GetValue 返回的对象不是类型为 Product 的对象。它只能转换为与属性相同的类型。2) LINQ 也不知道如何按 Product 排序。您必须根据原始类型排序。 - Corey Adler
1
因为在这种情况下,它并没有按Product对象本身进行排序。它是基于名称进行排序的,而名称是一个字符串原始类型。这是LINQ可以理解的排序方式。 - Corey Adler
1
OrderBy(x => x.Name); 是按照 Name 进行排序,而 Name 是一个字符串。如果要知道如何对产品进行排序,则会变得更加复杂。我认为您需要在 Product 类上实现 IComparable 接口才能通过 OrderBy 进行排序,尽管我不是100%确定。 - Greg B
此外,如果不知道你要做什么,这种方法似乎比直接编写代码效果要差。但是,为了使其正常工作,您需要将其转换为属性类型(再次强制转换为“Product”无效),因此在“Name”的情况下,请将其转换为字符串。 - Greg B
显示剩余4条评论

1
这并不像看起来那么简单。LINQ to SQL 引擎解析你传递给 OrderBy 方法的表达式,以获取你正在引用的属性的名称,然后使用此信息组合一个普通的 SQL order by 子句。
我猜可以通过反射完成,或者从 this SO question 的被接受的答案中获得一些有用的东西。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接