【问题标题】:Linq to Objects - Left Outer Join Distinct Object Property Values to an Aggregate CountLinq to Objects - 左外连接不同对象属性值到聚合计数
【发布时间】:2012-06-06 13:00:25
【问题描述】:

假设我有以下对象的通用列表:

public class Supermarket
{
    public string Brand { get; set; }
    public string Suburb { get; set; }
    public string State { get; set; }
    public string Country { get; set; }
}

所以使用List<Supermarket> 填充了许多具有不同值的对象,我正在尝试:

  1. Supermarket 对象的超集包含在 List<Supermarket> 中(比如这个超集包含 20 不同的郊区)。

  2. 将上面的 Distinct List of Suburbs 加入到另一组通过 LINQ 查询获得的聚合和计数的 Suburbs 到另一个较小的List<Supermarket>列表中

我的超集中的不同项目是:

"Blackheath"
"Ramsgate"
"Penrith"
"Vaucluse"
"Newtown"

我的聚合查询的结果是:

"Blackheath", 50
"Ramsgate", 30
"Penrith", 10

我想和他们一起得到

"Blackheath", 50
"Ramsgate", 30
"Penrith", 10
"Vaucluse", 0
"Newtown", 0

这是我迄今为止尝试过的:

var results = from distinctSuburb in AllSupermarkets.Select(x => x.Suburb).Distinct()
                select new
                {
                    Suburb = distinctSuburb,
                    Count = (from item in SomeSupermarkets
                            group item by item.Suburb into aggr
                            select new
                            {
                                Suburb = aggr.Key,
                                Count = aggr.Count()
                            } into merge
                            where distinctSuburb == merge.Suburb
                            select merge.Count).DefaultIfEmpty(0)
                } into final
                select final;

这是我第一次不得不在 Stack Overflow 上发帖,因为它是一个很棒的资源,但我似乎无法为此拼凑出一个解决方案。

感谢您的宝贵时间

编辑:好的所以我在最初的帖子后不久解决了这个问题。我唯一缺少的是在调用.DefaultIfEmpty(0) 之后链接到.ElementAtOrDefault(0) 的调用。我还验证了使用 .First() 而不是 Ani 指出的 .DefaultIfEmpty(0) 有效,正确的查询如下:

var results = from distinctSuburb in AllSupermarkets.Select(x => x.Suburb).Distinct()
                select new
                {
                    Suburb = distinctSuburb,
                    Count = (from item in SomeSupermarkets
                            group item by item.Suburb into aggr
                            select new
                            {
                                Suburb = aggr.Key,
                                Count = aggr.Count()
                            } into merge
                            where distinctSuburb == merge.Suburb
                            select merge.Count).DefaultIfEmpty(0).ElementAtOrDefault(0)
                } into final
                select final;

最后:我运行了 Ani 的代码 sn-p 并确认它运行成功,所以 两种 方法都可以工作并解决原始问题。

【问题讨论】:

    标签: linq left-join distinct aggregate-functions


    【解决方案1】:

    我不太理解 StateSuburb (where distinctSuburb == merge.State) 之间假定的等价关系,但您可以在 DefaultIfEmpty(0) 调用之后添加 .First() 来修正您的查询。

    但我会这样写你的查询:使用GroupJoin:

    var results = from distinctSuburb in AllSupermarkets.Select(x => x.Suburb).Distinct()
                  join item in SomeSupermarkets 
                            on distinctSuburb equals item.Suburb
                            into suburbGroup
                  select new
                  {
                        Suburb = distinctSuburb,
                        Count = suburbGroup.Count()
                  };
    

    【讨论】:

    • 谢谢阿尼。我用我原来的方法解决了这个问题,并解决了你指出的我错误地混淆了 State 和 Suburb 属性的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-14
    • 1970-01-01
    • 2013-09-09
    • 1970-01-01
    • 2010-10-14
    • 2015-08-26
    相关资源
    最近更新 更多