说我有两套;糖果和地区。对于每个Candy,我都会在某个区域(CandyRegion)中有一个叫做糖果的一对多名称。
我想构建一个Candy对象列表,其中只选择了一个CandyRegion.Name。选择的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 :(得分: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();
解释上面发生的事情......
由于Region和Candy都使用CandyRegion作为桥接表,您可以通过它的RegionId将Candy的外键集合CandyRegion分组。
这提供了一种确定每个分组集的计数的简便方法。既然你有计数,我们想要从最高到最低排序,并抓住最顶层的项目。我们不关心其余的事情。
一旦完成,只需选择列表中包含的第一个与确定的RegionId相匹配的CandyRegion,然后将它的CandyId与同一CandyRegion的CandyID进行比较。
最后,当这一切都完成后,你将结果作为一个列表返回,这就是你所追求的糖果。
答案 1 :(得分: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();