Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 分组和求和_C#_Linq - Fatal编程技术网

C# 分组和求和

C# 分组和求和,c#,linq,C#,Linq,我有一个如下的列表,其中将包含以下poco类 public class BoxReportView { public DateTime ProductionPlanWeekStarting { get; set; } public DateTime ProductionPlanWeekEnding { get; set; } public string BatchNumber { get; set; } public string BoxRef { get; se

我有一个如下的列表,其中将包含以下poco类

public class BoxReportView
{
    public DateTime ProductionPlanWeekStarting { get; set; }
    public DateTime ProductionPlanWeekEnding { get; set; }
    public string BatchNumber { get; set; }
    public string BoxRef { get; set; }
    public string BoxName { get; set; }
    public decimal Qty { get; set; }

    public FUEL_KitItem KitItem { get; set; }
    public decimal Multiplier { get; set; }
}
我想对报告进行分组,并使用BoxName和Qty对其求和,因此我尝试了以下方法

var results = from line in kitItemsToGroup
              group line by line.BoxName into g
              select new BoxReportView
              {
                  BoxRef = g.First().BoxRef,
                  BoxName = g.First().BoxName,                                          
                  Qty = g.Count()
               };
在我以前的报告中,我只是这样做的

var multiplier = finishedItem.SOPOrderReturnLine.LineQuantity - 
                 finishedItem.SOPOrderReturnLine.StockUnitDespatchReceiptQuantity;

foreach (KitItem kItem in kitItems.Cast<KitItem().Where(z => z.IsBox == true).ToList())
{
   kittItemsToGroup.Add(new BoxReportView() {
       BatchNumber = _batchNumber,
       ProductionPlanWeekEnding = _weekEndDate,
       ProductionPlanWeekStarting = _weekStartDate,
       BoxRef = kItem.StockCode,
       KitItem = kItem,
       Multiplier = multiplier,
       Qty = kItem.Qty });
   }
}

但由于我将其用作var,我无法确定处理分组和按框名称和数量求和的最佳方式。

这是否是最佳方式取决于您的优先级。处理速度重要吗?还是更重要的是代码易于理解、易于测试、易于更改和易于调试

LINQ的优点之一是,它尽量避免对源的枚举

您确定此代码的用户始终需要完整的集合吗?是现在,还是在不久的将来,有人只想要第一个元素?或者在他获取第20个元素并发现没有他感兴趣的内容后,决定停止枚举

使用LINQ时,尽量长时间返回
IEnumerable
。只有将解释您的LINQed数据的最终用户才能决定是只获取
FirstOrDefault()
,还是将
Count()
所有内容,还是将其放入字典,或其他任何内容。如果列表不打算用作列表,那么创建列表将浪费处理能力

你的LINQ代码和你的foreach做了一些完全不同的事情。唉,在StackOverflow上,人们在没有真正指定需求的情况下请求LINQ语句是很常见的。所以我得在你的LINQ陈述和foreach之间猜一些东西

需求
kitItems
的输入序列分组,该序列应为
Fuel\u kitItems
,分组为具有相同
BoxName
boxReportView
,并从每组中的每个
Fuel\u KitItem
中选择几个属性

var kitItemGroups = kitItems
    .Cast<Fuel_KitItem>()       // only needed if kitItems is not IEnumerable<Fuel_KitItem>
    // make groups of Fuel_KitItems with same BoxName:
    .GroupBy(fuelKitItem => fuelKitItem.BoxName,

        // ResultSelector, take the BoxName and all fuelKitItems with this BoxName:
        (boxName, fuelKitItemsWithThisBoxName) => new
        {
            // Select only the properties you plan to use:
            BoxName = boxName,

            FuelKitItems = fuelKitItemsWithThisBoxName.Select(fuelKitItem => new
            {
                 // Only Select the properties that you plan to use
                 BatchNumber = fuelKitItem.BatchNumber,
                 Qty = fuelKitItem.Qty,
                 ...

                 // Not needed, they are all equal to boxName:
                 // BoxName = fuelKitItem.BoxName
             })
            // only do ToList if you are certain that the user of the result
            // will need the complete list of fuelKitItems in this group
            .ToList(),
         });

效率改进:只要您不知道LINQ将如何使用,就不要将其列为列表。如果您知道需要group.FuelKitItems计数的可能性很高,那么我是否正确理解您的问题是
结果的类型是什么以及如何返回?如果这是您的问题:
返回results.ToList()
将返回一个
列表
@RenéVogt只是没有在那里看到它谢谢。但是问题还问什么是处理组和sum的最佳方式这是最好的方式吗?代码中的sum在哪里?@NetMage我最初使用的是count,但需要使用sum thanksCan更新您的问题以反映您需要什么?您不能求和
g
。对不起,您可以编辑您的问题以删除单词fuel please。???(1) 这不是一个问题,而是一个答案;(2) 所提到的问题包括:;(3) 燃料这个词怎么了?(4) 你为什么不编辑这个答案?
var kitItemGroups = kitItems
    .Cast<Fuel_KitItem>()       // only needed if kitItems is not IEnumerable<Fuel_KitItem>
    // make groups of Fuel_KitItems with same BoxName:
    .GroupBy(fuelKitItem => fuelKitItem.BoxName,

        // ResultSelector, take the BoxName and all fuelKitItems with this BoxName:
        (boxName, fuelKitItemsWithThisBoxName) => new
        {
            // Select only the properties you plan to use:
            BoxName = boxName,

            FuelKitItems = fuelKitItemsWithThisBoxName.Select(fuelKitItem => new
            {
                 // Only Select the properties that you plan to use
                 BatchNumber = fuelKitItem.BatchNumber,
                 Qty = fuelKitItem.Qty,
                 ...

                 // Not needed, they are all equal to boxName:
                 // BoxName = fuelKitItem.BoxName
             })
            // only do ToList if you are certain that the user of the result
            // will need the complete list of fuelKitItems in this group
            .ToList(),
         });
var kitItemGroups = ...

// I only need the KitItemGroups with a BoxName starting with "A"
var result1 = kitItemGroups.Where(group => group.BoxName.StartsWith("A"))
    .ToList();

// Or I only want the first three after sorting by group size
var result2 = kitItemGroups.OrderBy(group => group.FuelKitItems.Count())
    .Take(3)
    .ToList();