LINQ - 复杂排序

时间:2011-08-08 15:23:19

标签: c# linq

我正在使用LINQ(C#)查询Order元素表。每个订单都包含以下字段:

- ID
- OpenDate
- PriorityID
- StatusID
- Description

StatusID字段映射到Status表。 Status表的结构如下:

- ID
- Name

我需要按照优先级和状态对所有Order对象进行排序。 我可以成功获取按优先级排序的Order对象。我是通过这样做的 以下内容:

List<Order> orders = new List<Order>();
using (DBDataContext context = new DBDataContext())
{
  orders = (from o in context.Orders
            orderby (o.PriorityID.HasValue ? o.PriorityID : Int32.MaxValue)  ascending
            select o).ToList();
}

但我的问题是考虑到状态。

一旦订单对象按优先级排序,我需要对Order对象进行排序 按以下状态顺序:已取消,已打开,已布线和已交付。显著, 这些状态值的ID以随机,无用的顺序牢固设置。我无法改变它们。你可以告诉我,我也不能用alphbetical名字对状态进行排序。另外,我无法向我的数据库添加任何字段。任何人都可以告诉我如何在LINQ中解决这个问题?

谢谢!

3 个答案:

答案 0 :(得分:2)

我认为你可以通过实现IComparer来解决这个问题,并使用Linq来订购它。由于您的状态不是数字或字母顺序。

public class CustomComparer : IComparer<Status>
{
     public int Compare(Status statusA, Status statusB)
     {
       if (statusA.StatusName == "Cancelled" && statusB.StatusName == "Cancelled")
       {
          return 0; // equals
       } 
       else if (statusA.StatusName == "Cancelled" && statusB.StatusName != "Cancelled")
       {
          return 1; // A > B
       }
       ....
     }
}

然后

orders.OrderBy(x => x.Status, new CustomComparer())

希望这有帮助。

答案 1 :(得分:0)

只要状态列表保持一致,您就可以创建一个字符串,例如“COID”,并根据“COID”.indexOf(firstletterofstatus)比较两种状态。也许不是最好的软件实践,但它会起作用。

答案 2 :(得分:-1)

如果它不是一个长列表(即它将合理地适合内存),你可以在客户端对状态和相关订单之间的映射进行排序:

int StatusOrder(Status status) 
{
    switch(status.Id)
    {
       case 1: return 5;
       case 2: return 1;
       case 4: return 3;
       //etc
    }
}

List<Order> orders; //no need to create a list here
using (DBDataContext context = new DBDataContext())
{
    orders = (from o in context.Orders
        orderby (o.PriorityID.HasValue ? o.PriorityID : Int32.MaxValue)  ascending,
                SorderOrder(o.Status)
        select o).ToList();
}