我目前正在使用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)?
谢谢!
答案 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();