2014-07-23 17 views
0

我已經寫了一些linq,但我不滿意它。我想重構兩個linq語句(可能帶有一個嵌套的group by子句?)爲一個子句。linq重構(可能使用嵌套組by子句)

var queryDB = from res in Results 
     where res.SeasonYear == 2013 
      group res by res.resultDate into g 
      orderby g.Key 
      select new 
      { 
       ResultDate = g.Key 
       , ResultList = g.OrderByDescending(r => r.Value) 
      }; 

List<result> finalList = new List<result>(); 

foreach (var list in queryDB.Select(k=>k.ResultList).ToList()) 
{ 
    var query5 = from item in list 
     where item.member.classifications.First(c => c.ClassificationYear == 2013).Value != "U" 
     group item by item.member.classifications.First(c => c.ClassificationYear == ClassificationYear).Value into g 
     orderby g.Key 
     select g.ToList().OrderByDescending(r => r.Value).Take(3); 

     query5.ToList().ForEach(c => c.ToList().ForEach(r => finalList.Add(r))); 

} 

涉及的實體是:

public class Member 
{  
    public string Surname { get; set; } 
    public virtual ICollection<Result> Results { get; set; } 
    public virtual ICollection<Classification> Classifications { get; set; } 
} 
public class Result 
{ 
    public int Value { get; set; } 
    public int SeasonYear { get; set; } 
    public Member member { get; set; } 
} 
public class Classification 
{ 
    public string Value { get; set; } 
    public int ClassificationYear { get; set; } 
    public Member member { get; set; } 
} 

甲構件具有許多結果和許多分類(但每ClassificationYear只有一個分類)。

我需要產生一個特定年份(比如2013年)的結果列表,按日期排序。結果需要根據分類類的Value屬性進行分組,然後結果由結果類的Value屬性進行排序。

爲一棵樹,結果集/層次結構可能是這樣的:

13/04/2013 
    classification.Value = A 
     Result (Result.Value = 44) 
     Result (Result.Value = 41) 
     Result (Result.Value = 40) 
    classification.Value = B 
     Result (Result.Value = 42) 
     Result (Result.Value = 39) 
     Result (Result.Value = 36) 
    classification.Value = C 
     Result (Result.Value = 37) 
     Result (Result.Value = 35) 
     Result (Result.Value = 34)  

11/05/2013 
    classification.Value = A 
     Result (Result.Value = 40) 
     Result (Result.Value = 39) 
     Result (Result.Value = 38) 
    classification.Value = B 
     Result (Result.Value = 39) 
     Result (Result.Value = 38) 
     Result (Result.Value = 37) 
    classification.Value = C 
     Result (Result.Value = 38) 
     Result (Result.Value = 36) 
     Result (Result.Value = 35) 

但最終,所有我真正想要的是結果對象的平面列表:

Result (.Value= 44,.Date= 13/04/2013,.Member.Classification.Value for 2013= A) 
Result (.Value= 41,.Date= 13/04/2013,.Member.Classification.Value for 2013= A) 
Result (.Value= 40,.Date= 13/04/2013,.Member.Classification.Value for 2013= A) 
Result (.Value= 42,.Date= 13/04/2013,.Member.Classification.Value for 2013= B) 
Result (.Value= 39,.Date= 13/04/2013,.Member.Classification.Value for 2013= B) 
Result (.Value= 36,.Date= 13/04/2013,.Member.Classification.Value for 2013= B) 
Result (.Value= 37,.Date= 13/04/2013,.Member.Classification.Value for 2013= C) 
Result (.Value= 35,.Date= 13/04/2013,.Member.Classification.Value for 2013= C) 
Result (.Value= 34,.Date= 13/04/2013,.Member.Classification.Value for 2013= C) 
Result (.Value= 40,.Date= 11/05/2013,.Member.Classification.Value for 2013= A) 
Result (.Value= 39,.Date= 11/05/2013,.Member.Classification.Value for 2013= A) 
Result (.Value= 38,.Date= 11/05/2013,.Member.Classification.Value for 2013= A) 
Result (.Value= 39,.Date= 11/05/2013,.Member.Classification.Value for 2013= B) 
Result (.Value= 38,.Date= 11/05/2013,.Member.Classification.Value for 2013= B) 
Result (.Value= 37,.Date= 11/05/2013,.Member.Classification.Value for 2013= B) 
Result (.Value= 38,.Date= 11/05/2013,.Member.Classification.Value for 2013= C) 
Result (.Value= 36,.Date= 11/05/2013,.Member.Classification.Value for 2013= C) 
Result (.Value= 35,.Date= 11/05/2013,.Member.Classification.Value for 2013= C) 

第一linq語句按日期對數據進行分組,然後ResultList包含該日期的所有結果。

循環中的第二個linq語句然後處理每個ResultList,通過分類對數據進行分組(忽略一些分類)並對這些結果進行排序,最後得到前3個結果。這個循環也有(我認爲是)一個hndndous .ToList(ForEach(.ToList(.ForEach())))lambda表達式,以將層次結構展平爲結果對象列表。

所以,雖然這確實有效,但它非常可怕。我如何合併兩個linq語句並替換lambda表達式來平坦化結果?

+0

你應該問http://codereview.stackexchange.com/如果你需要一些幫助來重構你的代碼 – simoneL

+0

這需要selectmany函數 – Hogan

回答

0

OK,所以我想出了最後的LINQ是這樣的,在年底,包括向的SelectMany壓扁成一個列表:

var filteredResults = 
    from res in Results 
    where res.SeasonYear == 2013 
    orderby res.resultDate 
    group res by res.resultDate into dateGroup 
    select new 
    { 
     ResultDate = dateGroup.Key, 
     ResultList = 
     from r in dateGroup 
     where r.member.classifications.Single(c => c.year == 2013).Value != "U" 
     group r by r.member.classifications.Single(c => c.year == 2013).Value into classifications 
     orderby classifications 
     select new 
     { 
      ClassificationGroup = classifications.Key, 
      ClassificationList =          
       from r2 in classifications.OrderByDescending(r => r.Value).Take(3) 
       select r2 
     }   
    };  

    finalList = filteredResults.SelectMany(item => item.ResultList) 
           .SelectMany(inner=>inner.ClassificationList) 
           .ToList(); 
+0

嘗試在最後一行使用SelectMany()。你不應該需要ToList() – Hogan

+0

謝謝,我修改了使用SelectMany的最後一個語句,所以它現在變得更加整齊, – Jason