2015-02-06 90 views
1

假設我有兩組;糖果和地區。對於每個糖果,我都有一個糖果在某個區域(CandyRegion)中被稱爲的一對多名稱。從最高計數組中選擇值

我想創建一個只有一個CandyRegion.Name被選中的Candy對象列表。所選CandyRegion.Name由最受歡迎的地區(該地區可用的糖果數量最多)決定。

什麼是一種合適的方式來執行查詢來找到最流行的地區?我到目前爲止:

context.Candys 
    .Select(c => c.CandyRegions 
     .OrderByDescending(cr => 
      /* 
      * Order CandyRegion by Candy.CandyRegion.Count outside 
      * the context of c? 
      */ 
      context.CandyRegions.Count(cr2 => cr2.RegionId == cr.RegionId) 
     ) 
     .FirstOrDefault() 
    ) 
    .ToList(); 

我有一種感覺,上述查詢的性能將是一個問題。

編輯:類

public class Candy 
{ 
    public int Id { get; set; } 
    ... 

    public virtual List<CandyRegion> CandyRegions { get; set; } 
} 

public class Region 
{ 
    public int Id { get; set; } 
    ... 

    public virtual List<CandyRegion> CandyRegions { get; set; } 
} 

public class CandyRegion 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    ... 

    public int RegionId { get; set; } 
    public virtual Region Region { get; set; } 

    public int CandyId { get; set; } 
    public virtual Candy Candy { get; set; } 
} 
+0

你提到你有兩套。通過你的代碼片斷,糖果對象包含一系列糖果區域,是否正確?如果是這樣的話,你在技術上有一個包含一個集合的對象,而不是兩個單獨的集合,這意味着你需要某種連接子句。 – 2015-02-06 04:28:53

+0

@JamesShaw是的,CandyRegion是糖果和地區的集合。地區將是第二套。糖果和地區加入CandyRegion。 – 2015-02-06 04:42:13

+0

@DamonPollard我想你應該也發佈有問題的糖果和地區類!它會造成混淆。 – 2015-02-06 04:54:49

回答

0

任何具體的理由對查詢context用於獲取數量,同時你可以用你c.CandyRegion?

下面的查詢會導致連接並且使用context查詢會導致內部查詢。

context.Candy 
    .Select(c => c.CandyRegion 
     .OrderByDescending(cr => 
      /* 
      * Order CandyRegion by Candy.CandyRegion.Count outside 
      * the context of c? 
      */ 
      c.CandyRegion.Count() 
     ) 
     .FirstOrDefault() 
    ) 
    .ToList(); 
+0

這會讓我成爲最受歡迎的糖果(大多數地區的糖果),而不是糖果最多的地區。我想找到更晚的。 – 2015-02-06 04:40:05

+0

@DamonPollard查詢的哪一部分讓你認爲這會給你糖果實例而不是candyregion實例? – 2015-02-06 04:41:53

+0

對不起,我的意思是關於您所做的更改,而不是查詢的結果。 c.CandyRegion.Count()會給我最多區域的糖果,導致錯誤的順序。 – 2015-02-06 04:45:47

2

這應該可以做到,儘管我還沒有測試過。讓我知道這解決了你的問題。

Context.Candys 
       .Where(c => c.Id == c.CandyRegions 
        .FirstOrDefault(cr => cr.RegionId == c.CandyRegions 
         .GroupBy(grp => grp.RegionId) 
          .Select(r => new 
              { 
               RegionId = r.Key, 
               Total = r.Count() 
              } 
            ).OrderByDescending(r => r.Total) 
               .Take(1) 
               .First().RegionId 
            ).CandyId 
         ) 
         .ToList(); 

解釋什麼上面回事...

由於地區和糖果都使用CandyRegion作爲橋接表,你可以按它CandyRegion的糖果的外鍵集合的RegionId。

這提供了一種確定每個分組集的計數的簡單方法。現在你已經有了計數,我們想要從最高到最低的順序排列它們,並抓取最上面的項目。我們不關心其餘的事情。

完成後,只需選擇列表中包含的第一個與所確定的RegionId相匹配的CandyRegion,然後將其與CandyId與CandyRegion的CandyID進行比較即可。

最後,當這一切都完成後,您將結果作爲列表返回,這將成爲您所在的糖果。