【问题标题】:c# Linq - Select Top 2 from Each Groupc# Linq - 从每个组中选择前 2 名
【发布时间】:2015-10-15 14:22:26
【问题描述】:

我需要为每个 ProductTypeName 获取前 2 个产品:

var productDetails = (from p in products
                            join po in productOrganisations 
                            on p.Id equals po.ProductId
                            where po.OrganisationId == id
                            where p.ProductTypeId == (typeId > 0 ? typeId : p.ProductTypeId) //filter by type if specified
                            where p.IsLive
                            select new
                            {
                                Id = p.Id,
                                Name = p.Name,
                                SupplierName = p.Supplier.Name,
                                ProductTypeName = p.ProductType.Name,
                                ShortDescription = p.ShortDescription,
                                ProductTypeId = p.ProductTypeId,
                                DatePublished = p.DatePublished,
                                CurrencyId = p.CurrencyId,

                            })
                            .AsNoTracking()
                            .ToArray();

目前上述声明返回了我所有的产品,数百个。并且每个产品都有一个属性 ProductTypeName 。

我需要按此 ProductTypeName 进行分组,然后按发布日期降序获得每个组中的前两个。

有什么想法吗?

【问题讨论】:

  • 使用take功能

标签: c# linq group-by


【解决方案1】:

ChrisWue provides a good answer here。如果这解决了您的问题,请投他一票

强烈键入您的列表,然后使用GroupByOrderByTake 获取结果。

强烈键入您的结果集,如下所示:

List<ProductDetails> myProductList = (from p in products
                        join po in productOrganisations 
                        on p.Id equals po.ProductId
                        where po.OrganisationId == id
                        where p.ProductTypeId == (typeId > 0 ? typeId : p.ProductTypeId) //filter by type if specified
                        where p.IsLive
                        select new
                        {
                            Id = p.Id,
                            Name = p.Name,
                            SupplierName = p.Supplier.Name,
                            ProductTypeName = p.ProductType.Name,
                            ShortDescription = p.ShortDescription,
                            ProductTypeId = p.ProductTypeId,
                            DatePublished = p.DatePublished,
                            CurrencyId = p.CurrencyId,

                        })
                        .AsNoTracking()
                        .ToList();

然后像这样查询列表:

List<ProductDetail> finalResult = 
                     myProductList.GroupBy(p => p.ProductTypeName)
                     .SelectMany(d => d.OrderBy(r => r.DatePublished.Take(2))
                     .ToList();

【讨论】:

  • 您的解决方案看起来很可靠。我认为它可能在 DatePublished 上缺少“OrderBy”。
  • 这在很多情况下都非常有用且正确,但在我的现实生活场景中,我此时并没有强输入,因为我的结果集实际上有额外的列,纯粹用于存储计算值,稍后我从这些中选择并传递给强类型结果集。
【解决方案2】:

对于遇到相同问题的人,我最终使用以下方法解决了:

.GroupBy(x => x.ProductTypeId)
.SelectMany(x => x.Take(2))

所以完整的例子是:

var productDetails = (from p in products
                            join po in productOrganisations 
                            on p.Id equals po.ProductId
                            where po.OrganisationId == id
                            where p.ProductTypeId == (typeId > 0 ? typeId : p.ProductTypeId) //filter by type if specified
                            where p.IsLive
                            select new
                            {
                                Id = p.Id,
                                Name = p.Name,
                                SupplierName = p.Supplier.Name,
                                ProductTypeName = p.ProductType.Name,
                                ShortDescription = p.ShortDescription,
                                ProductTypeId = p.ProductTypeId,
                                DatePublished = p.DatePublished,
                                CurrencyId = p.CurrencyId,
                            })
                            .GroupBy(x => x.ProductTypeId)
                            .SelectMany(x => x.Take(2))
                            .AsNoTracking()
                            .ToArray();

这可行,但我想知道这是最好的方法吗?效率最高?

【讨论】:

    猜你喜欢
    • 2012-06-19
    • 2018-08-26
    • 1970-01-01
    • 1970-01-01
    • 2013-04-04
    • 1970-01-01
    • 1970-01-01
    • 2020-02-04
    • 1970-01-01
    相关资源
    最近更新 更多