如何简化此代码并删除一些循环?

How do I simplify this code and remove some loops?

是否可以用更少的 foreach 循环编写以下代码?

var pensInShed = _db.Pens.Where(w => w.ShedId == selectedShedGuid).Select(s => s.PensGuid);

                foreach(var penId in pensInShed)
                {
                    var pensInWeanedShed = _db.DailyConsumptionPens.Where(w => w.PenId == penId && w.Timestamp == ConvertedDate).Select(s => s.ConsumptionPenGuid);

                    foreach(var consumptionGuid in pensInWeanedShed)
                    {
                        var matchedUnits = _db.ConsumptionUnits.Where(w => w.DailyConsumptionId == consumptionGuid);

                        foreach(var unit in matchedUnits)
                        {
                            var unitLine = unit.UnitNETWeight * unit.UnitsUsed;

                            shedTotal += unitLine;
                        }
                    }

                    var pensToUpdate = _db.DailyConsumptionPens.Where(w => w.PenId == penId && w.Timestamp == ConvertedDate).ToList();

                    foreach(var pen in pensToUpdate)
                    {
                        pen.TotalShedUsage = shedTotal;
                        _db.SaveChanges();
                    }
                }

我不知道这是否可行,但我希望具有相同的功能,但其中的 foreach 循环更少。

如果没有关于该问题的更多数据,很难看到您想要的东西...

但我怀疑你可以像这样做一些事情(完全未经测试)...

但实际上,除非您遇到某种性能问题,否则我不会担心它。您拥有的代码比这更容易调试 - 我怀疑性能是否会有太大差异。根据 _db 是什么,这可能会导致对数据库执行汇总操作,这可能会提供更好的性能(由于将 LINQ 转换为 SQL),但这取决于很多其他东西......

foreach 循环本身并不坏。没有理由不使用它们。我们都出于风格和代码简洁的原因使用 Linq,但最后,如果系统正在处理内存中的数据,编译器最终将优化所有这些 looping/summing 东西以大致相同的方式。

var pensInShed = _db.Pens.Where(w => w.ShedId == selectedShedGuid).Select(s => s.PensGuid);

foreach(var penId in pensInShed)
{

    var shedTotal =
        _db.DailyConsumptionPens
            .Where(w => w.PenId == penId && w.Timestamp == ConvertedDate)
        .Sum(x =>
            _db.ConsumptionUnits
                .Where(w =>
                    w.DailyConsumptionId == x.ConsumptionPenGuid)
                .Sum(xx => xx.UnitNETWeight * xx.UnitsUsed)
        );


    var pensToUpdate = _db.DailyConsumptionPens
        .Where(w => w.PenId == penId && w.Timestamp == ConvertedDate)
        .ToList();

    foreach(var pen in pensToUpdate)
    {
        pen.TotalShedUsage = shedTotal;
        _db.SaveChanges();
    }
}