我有以下代码:
IQueryable<Guid> GetOrdered(IQueryable<Guid> ids)
{
return from id in ids join storedId in storedIds on id equals storedId.Id
orderby storedId.Something select id;
}
现在我想向 GetOrdered()
引入一个参数,并可选择将 orderby
更改为 orderby descending
。像这样:
IQueryable<Guid> GetOrdered(IQueryable<Guid> ids, bool descending)
{
// how do I insert descending into the query below?
return from id in ids join storedId in storedIds on id equals storedId.Id
orderby storedId.Something select id;
}
当然,我可以编写两个相同的查询 - 一个使用 orderby
,另一个使用 orderby descending
,但这意味着代码重复。
或者,我可以对无序集使用子语句,然后有条件地对其排序 like in this answer但问题是我需要 Select()
特定列,而后者 Select()
将呈现无序结果。
所以我可以尝试将“智能”订购条件设计为 in this answer :
var result = from w in widgets where w.Name.Contains("xyz")
orderby
flag ? w.Id : 0,
flag ? 0 : w.Id descending
select w;
但问题是我经常会有一个非数字列作为我需要按其排序的列。
如何在这些条件下有条件地反转排序顺序?
最佳答案
IQueryable<Guid> GetOrdered(IQueryable<Guid> ids, bool descending = false)
{
var results = from id in ids join storedId in storedIds on id equals storedId.Id
select id;
if (descending)
results = results.OrderByDescending(o => o.Something);
else
results = results.OrderBy(o => o.Something);
return results;
}
这是一种标准的东西。
但是,如果您需要按您实际上并未选择的内容进行排序,则需要将查询拆分为多个语句。您知道,逐步构建查询,就像我们在 ADO 时代所做的那样。首先进行排序,然后为选择指定列。因为您没有具体化结果,所以它应该只生成一个 sql 查询。
它可能看起来像这样。
IQueryable<Guid> GetOrdered(IQueryable<Guid> ids, bool descending = false)
{
var results = storedIds.Where(somecondition);
if (descending)
results = results.OrderByDescending(o => o.Something);
else
results = results.OrderBy(o => o.Something);
return results.Select(o => o.Id);
}
关于你的最后一句话..
but the problem is I will often have a non-numeric column as one by which I need my set ordered.
没错。可能有一种方法可以克服这个问题(比如使用一些工厂来生成要根据某些输入进行比较的值),但这对于这样的任务来说确实是一种矫枉过正。有时最简单的解决方案是最好的。过于通用的做事方式闻起来真的很糟糕。不要想太多这个问题;)
关于c# - 如何有选择地反转 Linq-to-Sql 中的排序顺序?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16895276/