2017-06-06 111 views
-1

我有一个集合,我试图以排序首先按季度排列记录,然后按季度排列最高排列量。到目前为止我的代码是为下如何执行OrderBy,然后执行OrderByDescending?

using System; 
using System.Collections.Generic; 
using System.Linq; 

namespace ConsoleApplication1 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      List<Test> lstTest = new List<Test>(); 
      lstTest.Add(new Test { dt = new DateTime(2017, 1, 2), amount = 2500 }); 
      lstTest.Add(new Test { dt = new DateTime(2017, 1, 2), amount = 10000 }); 
      lstTest.Add(new Test { dt = new DateTime(2017, 1, 5), amount = 4000 }); 
      lstTest.Add(new Test { dt = new DateTime(2017, 1, 10), amount = 40000 }); 
      lstTest.Add(new Test { dt = new DateTime(2017, 1, 15), amount = 2000 }); 
      lstTest.Add(new Test { dt = new DateTime(2017, 1, 25), amount = 12000 }); 
      lstTest.Add(new Test { dt = new DateTime(2017, 2, 5), amount = 38000 }); 
      lstTest.Add(new Test { dt = new DateTime(2017, 2, 10), amount = 38000 }); 
      lstTest.Add(new Test { dt = new DateTime(2017, 2, 15), amount = 4000 }); 
      lstTest.Add(new Test { dt = new DateTime(2017, 2, 20), amount = 2000 }); 
      lstTest.Add(new Test { dt = new DateTime(2017, 2, 20), amount = 20000 }); 
      lstTest.Add(new Test { dt = new DateTime(2017, 3, 15), amount = 2000 }); 
      lstTest.Add(new Test { dt = new DateTime(2017, 3, 20), amount = 2000 }); 
      lstTest.Add(new Test { dt = new DateTime(2017, 3, 20), amount = 4000 }); 
      lstTest.Add(new Test { dt = new DateTime(2017, 3, 31), amount = 1000 }); 
      lstTest.Add(new Test { dt = new DateTime(2017, 4, 9), amount = 50000 }); 
      lstTest.Add(new Test { dt = new DateTime(2017, 4, 11), amount = 2000 }); 
      lstTest.Add(new Test { dt = new DateTime(2017, 4, 21), amount = 1000 }); 
      lstTest.Add(new Test { dt = new DateTime(2017, 4, 21), amount = 10000 }); 
      lstTest.Add(new Test { dt = new DateTime(2017, 4, 28), amount = 5000 }); 
      lstTest.Add(new Test { dt = new DateTime(2017, 5, 5), amount = 45000 }); 
      lstTest.Add(new Test { dt = new DateTime(2017, 5, 7), amount = 98000 }); 
      lstTest.Add(new Test { dt = new DateTime(2017, 5, 9), amount = 7000 }); 
      lstTest.Add(new Test { dt = new DateTime(2017, 5, 25), amount = 2000 }); 
      lstTest.Add(new Test { dt = new DateTime(2017, 5, 31), amount = 1000 }); 

      var result = lstTest.Select(x => new 
      { 
       Amount = x.amount, 
       Date = x.dt, 
       MonthDiff = GetMonthsDiff(DateTime.Now, x.dt), 
       Quater = GetQuarter(DateTime.Now, x.dt) 
      }).OrderBy(o=>o.Quater).ToList(); 

      foreach (var res in result) 
      { 
       Console.WriteLine("Amount = {0} Date= {1} MonthDiff= {2} Quater= {3}", res.Amount, res.Date, res.MonthDiff, res.Quater); 
      } 
      Console.ReadKey(); 
     } 


     public static string GetQuarter(DateTime start, DateTime end)// int month) 
     { 
      int month = GetMonthsDiff(start, end); 
      string quarter = month <= 3 ? "Q1" : (month >= 4 && month <= 6) ? "Q2" : (month >= 7 && month <= 9) ? "Q3" : "Q4"; 
      return quarter; 
     } 



     public static int GetMonthsDiff(DateTime start, DateTime end) 
     { 
      if (start > end) 
       return GetMonthsDiff(end, start); 

      int months = 0; 
      do 
      { 
       start = start.AddMonths(1); 
       if (start > end) 
        return months; 

       months++; 
      } 
      while (true); 
     } 
    } 

    public class Test 
    { 
     public DateTime dt { get; set; } 
     public int amount { get; set; } 
    } 
} 

输出是

enter image description here

如果我做OrderBy(o=>o.Quater).OrderByDescending(o=>o.Amount)输出变为

enter image description here

也就是说它首先排序按季度再按金额

但我在寻找首先按季度排序,并在季内排序按金额 降

所需的输出是

enter image description here

需要什么在程序中进行修饰以达到目标?

非常感谢提前。

+1

你有一个错字:它是Quarter,而不是Quater。 –

+2

将您的第二个OrderBy更改为ThenBy。谷歌为“Enumerable ThenBy”https://msdn.microsoft.com/en-us/library/bb534743%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396 –

回答

1

你不需要单独排序只有财产。您可以将排序字段返回为匿名对象元组。

在C#7,你可以写:

OrderBy(o => (o.Quarter,o.Amount)); 

在以前的版本:

OrderBy(o => Tuple.Create(o.Quarter,o.Amount)); 

如果你想使用不同的排序顺序,必须指定的字段一次一个,如:您可以使用查询语法使代码更清洁:

var result = (from x in lstTest 
       let o = new { 
          Amount = x.amount, 
          Date = x.dt, 
          MonthDiff = GetMonthsDiff(DateTime.Now, x.dt), 
          Quarter = GetQuarter(DateTime.Now, x.dt) 
          } 
       orderby o.Quarter, o.Amount descending 
       select o 
      ).ToList() 
+0

第一部分是错误的 - 你可以'按匿名类型排序。尽管编译器为匿名类型实现了值相等,但它并未实现比较。 –

+0

@IvanStoev你是对的。它适用于元组,不管新旧。 –

10

OrderBy(o=>o.Quater).ThenByDescending(o=>o.Amount) 

ThenByDescending取代

OrderBy(o=>o.Quater).OrderByDescending(o=>o.Amount) 

执行在通过使用指定的比较降序在 序列中的元素的后续排序。

3

这里要排序列表两次,你只得到最终排序的输出,如果你想通过你必须利用ThenByDescending(第一则的排序结果进行第二次排序如果你想在递减的顺序,或者使用ThenBy()其次是排序依据为这样的第二排序):

var sortedItems = lstTest.OrderBy(o=>o.Quater).ThenByDescending(o=>o.Amount); 

我在this example这里修改了代码,你可以检查输出的小提琴

相关问题