2011-09-11 51 views
1

鑑於類:你可以在一個linq語句中加上多個值嗎?沒有分組?

public class FooAmounts 
int Id 
decimal Month1 
decimal Month2 
... 
decimal Month12 
decimal Year2 
decimal Year3 
decimal Future 

我有IEnumerable<FooAmounts>有5項(編號的1-5有趣的是!)

我想創造出具有每月總計單個新FooAmounts /年但只有在Id == 1 + Id == 2 例如

var footle = (from f in foolist 
where f.Id == 1 || f.Id == 2 
select new FooAmounts{ 
Month1 = Sum(month 1s), 
Month2 = Sum(month 2s), 
etc etc. 
Future = Sum(futures) 
).FirstOrDefault(); 

我試圖重新創建這個T-SQL:

select SUM(Month1) as Month1, SUM(Month2) as Month2, SUM(Month3) as Month3 from FooAmount where Id=1 or Id=2" 

我可以acheive類似使用group by f.Id into grp條款但給我留下了兩個項目,因此,我不能先用/ FoD,這意味着我將不得不手動總結他們......這似乎是我必須錯過某個地方的把戲嗎?

注意:FirstOrDefault()僅在那裏,因此我找回單個對象而不是包含一個對象的枚舉。我認爲(也許是錯誤的!),總是應該只返回一個項目...... Sum()只有一個結果,不管有多少項目進入計算。

回答

1

無論您是否有一個或多個值,採取總和的第一個結果是沒有意義的。

如果我有10人,我能找到的第一個時代,或者我能找到的歲所有他們的總和 - 但我不能找到第一總和青睞。所以你可以這樣做:

var matches = fooList.Where(f => f.Id == 1 || f.Id == 2); 

var sum = new FooAmounts { Month1 = matches.Sum(f => f.Month1), 
          Month2 = matches.Sum(f => f>Month2), 
          ... }; 

當然,這將執行多次查詢。你可以兌現的查詢,而不是,然後做求和是:

// Materialize the result so we only filter once 
var matches = fooList.Where(f => f.Id == 1 || f.Id == 2).ToList(); 

var sum = new FooAmounts { Month1 = matches.Sum(f => f.Month1), 
          Month2 = matches.Sum(f => f>Month2), 
          ... }; 

或者你也可以使用聚合:

var sum = fooList.Where(f => f.Id == 1 || f.Id == 2) 
        .Aggregate(new FooAmounts(), // Seed 
          (sum, item) => new FooAmounts { 
           Month1 = sum.Month1 + item.Month1, 
           Month2 = sum.Month2 + item.Month2, 
           ... 
          }); 

這隻會在序列重複一次,而不是創建一個大內存中的緩衝區,但會迭代時創建大量的FooAmounts實例。

可以修改累加器的地方,當然:

var sum = fooList.Where(f => f.Id == 1 || f.Id == 2) 
        .Aggregate(new FooAmounts(), // Seed 
          (sum, item) => { 
           sum.Month1 += item.Month1; 
           sum.Month2 += item.Month2; 
           ... 
           return sum; 
          }); 

那感覺略有討厭我,但它在一個糟糕的方式不真的有副作用,因爲它只是改變在通話內初始化的對象。

+0

Apols,可能措辭很糟糕。我只想在包含總數的末尾返回一個單個對象,而不是每個月的對象列表(我已經擁有)或必須執行Sum(s => s.property)...年我想要的。 – BlueChippy

+0

@BlueChippy:我已經編輯了一些更多選項。不過,我認爲除了這些選項之外,還有什麼簡單和優雅的東西。 –

+0

感謝喬恩 - 我曾希望重新創建這個t-sql等效「選擇SUM(Month1)作爲Month1,SUM(Month2)作爲Month2,SUM(Month3)作爲Month3 從FooAmount其中Id = 1或Id = 2」:) – BlueChippy

相關問題