如何实现按Manufacturer、WarehouseItemDefinition分组的仓库物品过滤返回结构
实现多层嵌套分组过滤的思路
嘿,我来帮你理清楚这个多层分组的实现步骤,咱们从数据查询到分组映射一步步来:
第一步:调整查询,获取关联名称
首先你需要修改现有查询逻辑,把Manufacturer和WarehouseItemDefinition的名称一并查出来,不然分组后没法填充名称字段。用EF的话,可以通过Join或者Include+投影来实现,确保每条WarehouseItem都带上对应的厂商名称和物料定义名称。
比如用LINQ查询的示例:
// 先过滤,再关联查询名称 var filteredItemsWithNames = await _dbContext.WarehouseItems .Where(item => /* 这里放你现有WarehouseItemFilterDto的过滤条件 */) // 关联Manufacturer拿名称 .Join(_dbContext.Manufacturers, item => item.ManufacturerId, manufacturer => manufacturer.Id, (item, manufacturer) => new { Item = item, ManufacturerName = manufacturer.Name }) // 关联WarehouseItemDefinition拿名称 .Join(_dbContext.WarehouseItemDefinitions, combined => combined.Item.WarehouseItemDefinitionId, definition => definition.Id, (combined, definition) => new { combined.Item, combined.ManufacturerName, DefinitionName = definition.Name }) .ToListAsync();
第二步:按层级分组并排序
接下来就是核心的分组逻辑,按照你需要的层级:Manufacturer → WarehouseItemDefinition → WarehouseItem,同时在每个层级应用排序规则:
- 先按
ManufacturerId和ManufacturerName分组(确保同厂商的项归为一组),然后对厂商组排序; - 每个厂商组内,再按
WarehouseItemDefinitionId和DefinitionName分组,对物料定义组排序; - 每个物料定义组内,对WarehouseItem按
Lot Date→Color→Quality排序。
用LINQ实现分组映射的示例:
var nestedResult = filteredItemsWithNames // 第一级:按厂商分组 .GroupBy(x => new { x.Item.ManufacturerId, x.ManufacturerName }) .Select(manufacturerGroup => new WarehouseFilterResultDto { ManufacturerId = manufacturerGroup.Key.ManufacturerId, ManufacturerName = manufacturerGroup.Key.ManufacturerName, // 第二级:每个厂商组内按物料定义分组 ItemDefinitions = manufacturerGroup .GroupBy(x => new { x.Item.WarehouseItemDefinitionId, x.DefinitionName }) .Select(definitionGroup => new WarehouseItemDefinitionFilterDto { DefinitionId = definitionGroup.Key.WarehouseItemDefinitionId, DefinitionName = definitionGroup.Key.DefinitionName, // 第三级:每个物料定义组内的WarehouseItem排序并映射为Dto WarehouseItems = definitionGroup .Select(x => /* 调用你现有WarehouseItem到WarehouseItemDto的映射方法 */) .OrderBy(itemDto => itemDto.LotDate) .ThenBy(itemDto => itemDto.Color) .ThenBy(itemDto => itemDto.Quality) .ToList() }) .OrderBy(defDto => defDto.DefinitionName) // 按物料定义名称排序,也可以按Id .ToList() }) .OrderBy(resultDto => resultDto.ManufacturerName) // 按厂商名称排序,也可以按Id .ToList();
第三步:验证和优化
- 如果你的项目用了AutoMapper,可以配置从分组后的匿名类型到目标DTO的映射规则,减少手动映射的代码;
- 注意查询性能:如果数据量较大,建议用
AsNoTracking()优化查询,或者考虑是否需要分页(如果返回结果集很大的话); - 排序规则可以根据需求调整,比如厂商如果需要按Id排序,就把
OrderBy改成OrderBy(resultDto => resultDto.ManufacturerId)。
这样就能得到你需要的多层嵌套结构,同时满足所有排序要求啦!
内容的提问来源于stack exchange,提问作者grozdeto
相关产品推荐
相关产品推荐

