如何选择反转Linq-to-Sql中的排序顺序?

时间:2013-06-03 11:05:45

标签: c# .net linq-to-sql

我有以下代码:

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;

但问题是我经常会有一个非数字列作为我需要我的订单的订单。

如何在这些条件下有条件地撤销排序顺序?

2 个答案:

答案 0 :(得分:4)

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时代所做的那样。首先进行排序,然后指定select的列。因为您没有实现结果,所以它应该只生成一个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);
}

关于你的最后一句......

  

但问题是我经常会有一个非数字列作为一个   我需要订购我的套装。

这是真的。可能有一种方法可以克服这个问题(比如使用一些可以根据某些输入生成值进行比较的工厂),但这对于像这样的任务来说实在是太过分了。有时最简单的解决方案是最好的。太通用的做事方式可闻起来非常糟糕。不要过分思考问题;)

答案 1 :(得分:1)

要在Linq中实现条件OrderBy,您可以执行以下操作:

var flag = sortOrder == "asc";

result.OrderBy(o => flag ? o.Something: "").ThenByDescending(o => flag ? "" : o.Something).ToList();

适合我。