C#LINQ OrderBy有几个子句

时间:2017-07-07 13:43:18

标签: c# asp.net linq

我目前正在使用ASP.NET MVC 4.5中的应用程序。我需要编写一个LINQ查询来按不同的StatusIds排序项目列表。

给出了一个包含此ViewModel的项目列表:

public class ProjectVm 
{
   public int ProjectId { get; set; }
   public string Title { get; set; }
   public Status StatusId { get; set; }
}

我的项目状态枚举:

public enum Status : byte
{
    Draft = 1,
    Pending = 2,
    Validated = 3,
    Refused = 4
}

我们的想法是将List<ProjectVm>按照特定顺序排列,首先按 1草稿 排序,然后按 2等待排序 ,第三个是 4拒绝 ,第四个是 3已验证

我当前的查询如下所示:

projects = projects.OrderBy(x => x.StatusId).ToList();

不幸的是,这个查询不符合所需的顺序(4在3之前)。

您是否知道如何在此查询中应用条件以使项目按正确的顺序(1,2,4,3)?

谢谢!

6 个答案:

答案 0 :(得分:1)

只需使用多个订单,第一个订单为OrderByDescending,其余订单为ThenByDescending

projects = projects
    .OrderByDescending(p => p.StatusId == Status.Draft)
    .ThenByDescending(p => p.StatusId == Status.Pending)
    .ThenByDescending(p => p.StatusId == Status.Refused)
    .ThenByDescending(p => p.StatusId == Status.Validated)
    .ToList();

答案 1 :(得分:1)

没有一种干净的方法可以完全内联 - 你可以做类似的事情:

projects.OrderBy(x => x == Status.Validated ? int.MaxValue : (int)x.StatusId)

强制验证到最后,但我会编写一个函数:

private int CustomOrder(Status status)
{
    switch(status)
    {
       // force Validated to the end
        case Status.Validated:
            return int.MaxValue;
        default:
            return (int)status;
    }
}

并从查询中调用它:

projects.OrderBy(x => CustomOrder(x))

因为您可以添加注释并组织代码,以使您的意图更清晰。

另一种选择是按照你想要的顺序将值放在数组中,然后按它们在数组中的位置排序:

Status[] order = new [] {Draft, Pending, Refused, Validated};

projects.OrderBy(x => Array.IndexOf(order,x));

答案 2 :(得分:1)

试试这个:

public static int MyCustomOrder (Status status)
{
    switch (status)
    {
        case Status.Draft     : return 1;
        case Status.Pending   : return 2;
        case Status.Validated : return 4;
        case Status.Refused   : return 3;

        default: return -1;
    }
}

现在:

var result = projects.OrderBy (x => MyCustomOrder (x.StatusId));

答案 3 :(得分:1)

不是很漂亮,但应该有效:

projects.OrderBy(x => x.StatusId).ThenBy(c => c.StatusId == Status.Validated ? 1 : 0).ToList();

否则你需要提供自己的Comparer:

class StatusComparer : IComparer<Status>
        {
            public int Compare(Status x, Status y)
            {
                if (x.Equals(y)) return 0;
                return (x > y || x.Equals(Status.Validated)) ? 1 : -1;
            }
        }

然后致电:

projects.OrderBy(x => x.StatusId, new StatusComparer()).ToList();

或者像这里提出的其他人一样;)

答案 4 :(得分:1)

projects.OrderBy(x => x.StatusId == Status.Validated).ThenBy(x => x.StatusId)

在结尾处放置所有待处理的内容,然后通过StatusID在该规则中排序。两个简单的操作,任何提供商都可以很好地处理。

projects.OrderBy(x => x.StatusId == Status.Validated ? int.MaxValue : (int)x.StatusId)

单个操作,因此可能更快,在排序之前将3 Pending重新分配给int.MaxValue

我尝试第二个可能更有效率,但第二个也值得注意作为一般方法。

答案 5 :(得分:-1)

试试这个

var projectList= projects.OrderBy(x => (int)x.StatusId).ToList();