2015-02-06 89 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进行比较即可。

最后,当这一切都完成后,您将结果作为列表返回,这将成为您所在的糖果。