Linq OrderBy属性值和组

时间:2010-09-28 22:13:29

标签: c# linq

我基本上有一个带有标题的表,我在C#中使用linq从DB读入。在这些标题中,始终至少有一个始终相同; Total和我希望它总是在右边。

所以这里有一些我的数据如何布局:

Data
{
   Label,
   Value,
   Age  //Not used initially
}

示例数据:

{"Dog", 7}
{"Cat", 3}
{"Other", 4}
{"Total", 14}

我想按此顺序订购标签;实际的动物名称按其值按降序排序,总计附加到结尾:

"Dog", "Other", "Cat", "Total"

我如何在Linq中执行此操作。如何根据另一个属性的值订购属性?

一旦我获得了标题的顺序,是否有一种简单的方法可以根据已经确定的顺序订购未来的行。如果我想最初找到标题(x => x.Age> 20) 如何根据与> 20集相同的顺序对标签进行排序(x => x.Age< = 20)?

1 个答案:

答案 0 :(得分:4)

此查询应该有效:

var query = from row in table
            let ignore = row.Label == "Total"
            orderby ignore, row.Value descending
            select row.Label;

//and corresponding lambda version
var lquery = table.OrderBy(row => row.Label == "Total")
                  .ThenByDescending(row => row.Value)
                  .Select(row => row.Label);

注意:创建ignore变量并不是完全必要的,它可以直接放在orderby子句中。这样,它使它更具可读性。

在第二个问题中不确定你在问什么。


修改
在回应你的评论时,这将取决于你希望排序如何工作,至少写得这样。如果表中只有一行要完全忽略,则此方法很有效。如果你不止一个,那就不那么重要了。问题是在“被忽略”的行中,也将按原始排序进行排序(在本例中为Value)。添加另一行的一种天真的方法是添加到忽略条件。

var query = from row in table
            let ignore = row.Label == "Total" || row.Label == "Cost"
            orderby ignore, row.Value descending
            select row.Label;

要在“忽略”行中进行特定排序,需要更复杂的查询:

var query = from row in table
            let ignore = row.Label == "Total" || row.Label == "Cost"
            let ignoreorder = row.Label == "Cost" ? 1 : 0
            orderby ignore, ignoreorder, row.Value descending
            select row.Label;

//and corresponding lambda version
var lquery = table.OrderBy(row => row.Label == "Total" || row.Label == "Cost")
                  .ThenBy(row => row.Label == "Cost" ? 1 : 0)
                  .ThenByDescending(row => row.Value)
                  .Select(row => row.Label);