Bạn có thể gọi Sum
ba lần, nhưng sẽ chậm hơn vì sẽ thực hiện ba vòng.
Ví dụ:
var list = ArticleLedgerEntries.Where(pd => pd.LedgerEntryType == LedgerEntryTypeTypes.Unload
&& pd.InventoryType == InventoryTypes.Finished))
var totalWeight = list.Sum(pd => pd.GrossWeight);
var totalLength = list.Sum(pd => pd.Length);
var items = list.Sum(pd => pd.NrDistaff);
Bởi vì thực hiện chậm, nó cũng sẽ đánh giá lại các Where
gọi mọi thời gian, mặc dù đó không phải là như vậy một vấn đề trong trường hợp của bạn. Điều này có thể tránh được bằng cách gọi ToArray
, nhưng điều đó sẽ gây ra một phân bổ mảng. (Và nó vẫn chạy ba vòng)
Tuy nhiên, trừ khi bạn có số lượng mục nhập rất lớn hoặc đang chạy mã này trong một vòng lặp chặt chẽ, bạn không cần phải lo lắng về hiệu suất.
EDIT: Nếu bạn thực sự muốn sử dụng LINQ, bạn có thể lạm dụng Aggregate
, như thế này:
int totalWeight, totalLength, items;
list.Aggregate((a, b) => {
weight += detail.GrossWeight;
length += detail.Length;
items += detail.NrDistaff;
return a;
});
Đây là mã phi thường xấu xí, nhưng nên thực hiện hầu như cũng như một vòng lặp thẳng.
Bạn cũng có thể tính tổng trong bộ tích lũy, (xem ví dụ bên dưới), nhưng điều này sẽ phân bổ một đối tượng tạm thời cho mọi mục trong danh sách của bạn, đó là một ý tưởng ngớ ngẩn. (Loại Anonymous là không thay đổi)
var totals = list.Aggregate(
new { Weight = 0, Length = 0, Items = 0},
(t, pd) => new {
Weight = t.Weight + pd.GrossWeight,
Length = t.Length + pd.Length,
Items = t.Items + pd.NrDistaff
}
);
LINQ không phải là tất cả và kết thúc tất cả các thao tác dữ liệu, và vẫn không có gì sai với vòng lặp for. – SLaks
Hài hước mặc dù @SLaks rằng đây là một trong những trường hợp hiếm hoi mà LINQ không cung cấp một giải pháp hợp lý. – PeterX