LINQ 分组查询

Posted

技术标签:

【中文标题】LINQ 分组查询【英文标题】:LINQ Grouping a query 【发布时间】:2019-02-11 09:42:52 【问题描述】:

我最初问了一个问题,因为我遇到了一个类似的查询错误,我找到了解决这个问题的帮助,我现在有一个问题/需要一点帮助来了解如何制定正确的退货组,这将用于 WEB API 并且需要以某种方式分组的输出,我无法到达那里。

类-

public class GoodInWarehouseBM

    /// <summary>
    /// Pallet Number
    /// </summary>
    public string pallet_identifier  get; set; 

    public List<ShipmentItems> shipment_items  get; set; 

    public class ShipmentItems
    
        /// <summary>
        /// SKU Code
        /// </summary>
        public string sku  get; set; 

        /// <summary>
        /// Products on Pallet
        /// </summary>
        public decimal stock_qty  get; set; 
        /// <summary>
        /// Description of Item
        /// </summary>
        public string description  get; set; 

    

方法-

public IQueryable<IGrouping<string, GoodInWarehouseBM>> GetWarehouseToStoreList(string storeId)

    var entity = (from consighdrs in mi9TestEntities.consighdrs
                  join consigdests in mi9TestEntities.consigdests on consighdrs.consignment equals consigdests.consignment
                  join consigliness in mi9TestEntities.consiglines on consigdests.condestint equals consigliness
                      .condestint
                  join productcodess in mi9TestEntities.productcodes on consigliness.varint equals productcodess.varint
                  join products in mi9TestEntities.products on productcodess.prodint equals products.prodint
                  where consigdests.destination == storeId && consighdrs.status == "T"
                  select new GoodInWarehouseBM()
                  
                      pallet_identifier = consigdests.consignment,
                      shipment_items = new List<GoodInWarehouseBM.ShipmentItems>
                    new GoodInWarehouseBM.ShipmentItems
                    
                        sku = productcodess.variantcode,
                        stock_qty = consigliness.issueqty,
                        description = products.proddesc
                    

                  ).GroupBy(x => x.pallet_identifier);

    return entity;

输出 -

[
    [
        
            "pallet_identifier": "FS300057058",
            "shipment_items": [
                
                    "sku": "051657",
                    "stock_qty": 1,
                    "description": "BELT 1.25\" 5028"
                
            ]
        ,
        
            "pallet_identifier": "FS300057058",
            "shipment_items": [
                
                    "sku": "10121781",
                    "stock_qty": 1,
                    "description": "SLAZ CREW SWEAT"
                
            ]
        ,

想要的输出 -

[
  
    "pallet_identifier": "FS300057058",
    "shipment_items": [
            
              "sku": "051657",
              "stock_qty": 1,
              "description": "BELT 1.25\" 5028"
            ,
            
              "sku": "10121781",
              "stock_qty": 1,
              "description": "SLAZ CREW SWEAT"
            
        ]
    
]

我似乎在这里总结了如何真正得到这个结果,任何帮助和指点都将不胜感激。

【问题讨论】:

能否请您说明一下您是如何使用上述GetWarehouseToStoreList 函数的? 【参考方案1】:

重新排序,以便您 GroupBy 然后将每个组选择到您想要的对象中:

...
.GroupBy(x => x.consigdests.consignment)
.Select(x => new GoodInWarehouseBM

    pallet_identifier = x.Key,
    shipment_items = x.Select(i => new GoodInWarehouseBM.ShipmentItems
    
        sku = x.productcodess.variantcode,
        stock_qty = x.consigliness.issueqty,
        description = x.products.proddesc
    
);

由于我不习惯类似 SQL 的 LINQ 语法,因此您可能不得不稍微调整一下语法。我建议尽可能学习使用基于 lambda 的语法。

【讨论】:

感谢您的回复,我将开始重新编写 lambda,我只是发现类似 SQL 的语法更易于个人阅读,尤其是在有这么多连接的情况下。 当您在 c# 语法中进行连接时,通常使用导航属性。这让我在 99% 的情况下都能成功,但我确实同意,当我绝对必须执行 JOIN 时,它在 SQL 语法中的读取比使用笨重的 GroupJoin 函数更好。【参考方案2】:

您需要在应用分组后选择您的分组结果

...
).GroupBy(x => x.pallet_identifier)
  .Select(x => new GoodInWarehouseBM  pallet_identifier = x.Key, shipment_items = x.ToList() );

并将您的方法返回类型更改为List&lt;GoodInWarehouseBM&gt; 而不是IQueryable&lt;IGrouping&lt;string, GoodInWarehouseBM&gt;&gt;

或者你可以使用传统的 linq 查询,

var entity = (from consighdrs in mi9TestEntities.consighdrs
...
...
...
where consigdests.destination == storeId && consighdrs.status == "T"
group new  consigdests, productcodess, consigliness, products  by consigdests.consignment into grp
select new GoodInWarehouseBM

    pallet_identifier = grp.Key,
    shipment_items = grp.Select(a => new ShipmentItems
    
        sku  = a.productcodess.variantcode,
        stock_qty = a.consigliness.issueqty,
        description = a.products.proddesc
    )  
).ToList();

【讨论】:

感谢您的回复,但我无法选择 a.productcodess.variantcode 等,我需要将它们添加到组中才能选择吗? 答案已更新,试试看告诉我。请注意这一行 => group new consigdests, productcodess, consigliness, products by consigdests.consignment into grp 效果很好!我不得不将 public List 更改为 IEnumerable 但它起作用了,感谢您的帮助,我现在已经学会了如何在未来做到这一点。 IEnumerable 是一个接口,而 ToList 是一个具体类的查询。此链接将帮助您了解差异 => https://***.com/a/17449053/5514820 这也有助于你理解 => ***.com/a/23033688/5514820 and c-sharpcorner.com/forums/ienumerable-vs-list and ***.com/questions/3628425/…

以上是关于LINQ 分组查询的主要内容,如果未能解决你的问题,请参考以下文章

如何正确分组我的 LINQ 查询?

实体框架 LINQ - 具有分组依据的子查询

linq 中的分组查询

Linq分组查询

linq 多表分组查询统计

使用 .NET Core 进行分组的 Linq 查询