LINQ求和嵌套组在一个语句中

本文关键字:一个 语句 求和 嵌套 LINQ | 更新日期: 2023-09-27 18:10:25

我正在将一些代码转换为LINQ,同时探索LINQ可以完成的程度。

下面的代码可以压缩成一个LINQ查询或方法吗?

Dictionary<string, ItemPack> consolidated = new Dictionary<string, ItemPack>();
foreach (var product in Products)
{
    foreach (var smallpack in product.ItemPacks)
    {
        ItemPack bigpack;
        if (consolidated.TryGetValue(smallpack.ItemCode, out bigpack))
        {
            // the big pack quantity += quantity for making one product * the number of that product
            bigpack.Quantity += smallpack.Quantity * product.Quantity;
            // References: we make sure that the small pack is using the Item in the big pack.
            // otherwise there will be 2 occurance of the same Item
            smallpack.Item = bigpack.Item;
        }
        else
        {
            bigpack = new ItemPack(smallpack); // Copy constructor
            bigpack.Quantity = smallpack.Quantity * product.Quantity;
            consolidated.Add(smallpack.ItemCode, bigpack);
        }
    }
}
return consolidated;

在英语中,每个产品是由几个不同数量的产品组成的。这些物品按物品代码分组,并打包成小包。这些小包作为一个整体产品一起装运。有许多不同的产品。一个项目可以用于不同的产品。

我现在有一份产品清单和每种产品所需的装运数量。我想要一个LINQ语句来合并一个项目及其数量的平面列表。

我已经得到了这一点,但它看起来不工作:

var packsQuery = from product in Products
                 from smallpack in product.ItemPacks
                 select new {Item = smallpack.Item, Quantity = smallpack.Quantity * product.Quantity};
foreach (var pack in packsQuery)
{
    consolidated.Add(pack.Item.ItemCode, new ItemPack(pack.Item, pack.Quantity));
}

如果我先分组,那么我不能为其数量选择项目。如果我先选择,就会失去分组。鸡和蛋的故事?

编辑:有用提示:smallpack的类型是ItemPack,它看起来像这样

public class ItemPack
{
     Item { get; } // The item in this pack, which *must* be a shared reference across all objects that uses this Item. So that change in Item properties are updated everywhere it is used. e.g. Price.
     ItemCode { get; } // The item code
     Quantity { get; } // The number of such Item in this pack.
}

LINQ求和嵌套组在一个语句中

    var query = (from product in Products
                from smallPack in product.ItemPacks
                select new
                {
                    ItemCode = smallPack.ItemCode,
                    Item = smallPack.Item,
                    Quantity = smallPack.Quantity * product.Quantity,
                })
                .GroupBy(p => p.ItemCode)
                .Select(p => new
                {
                    ItemCode = p.Key,
                    Item = p.FirstOrDefault(),
                    Quantity = p.Sum(x=>x.Quantity)
                })
                .ToDictionary(p=>p.ItemCode);

谢谢你给我指明了方向。我设法找出了完整的查询语法版本:

var query = from product in Products
            from smallpack in product.ItemPacks
            select new {
                Item = smallpack.Item,
                Quantity = smallpack.Quantity * product.Quantity
            } into mediumpack
            group mediumpack by mediumpack.Item.ItemCode into bigpack
            select new {
                Item = bigpack.First().Item, // shared reference
                Quantity = bigpack.Sum(a => a.Quantity);
            }
query.ToDictionary(...);

有什么意见,这是好的吗?