2012-01-18 94 views
2

總結號碼我有以下數據:LINQ - 存儲爲字符串

PK OrderNumber  USERDEFFIELD 
1  0001    10 
2  0001    25 
3  0002    20 
4  0002    22 
5  0002    NULL 
6  0003    ABC123 

的UserDefField列是在數據庫VARCHAR類型。使用LINQ,如何獲得每個訂單的SUM(UserDefField)? UserDefField的NULL和非數字值將被視爲零。結果我試圖得到:

OrderNumber TotalQty 
0001   35 
0002   42 
0003   0 

如果UserDefField是嚴格爲空的數字字段,我知道我會做這個foreach循環中:

TotalQtyForThisOrder = orders.Sum(w => w.UserDefField ?? 0); 

但對於字符串字段,應該是什麼做了什麼?非常感謝你的幫助。

+0

入住這http://stackoverflow.com/questions/5754218/convert-string-to-int-in-ef-4-0 – ivowiblo 2012-01-18 21:00:22

回答

5
TotalQtyForThisOrder = orders.Sum(w = > { 
      int result; 
      Int32.TryParse(w.UserDefField, out result); 
      return result; 
}); 
+1

@ DavidHoerster:不正確。你可以初始化它,這樣做沒有意義。 – 2012-01-18 21:10:03

+0

對不起 - 我錯了。也許我需要更多的睡眠(或更多的咖啡因)。 – 2012-01-18 21:17:41

6

從根本上說,我會說你的模式是關閉:如果你處理文本值的號碼,如果碰巧是可分析的那樣,你真的對抗聰明的設計。

我不知道你怎麼能寫一個LINQ查詢來使這個總和在數據庫中發生。你可能想編寫一些自定義轉換函數,或者可能是一個自定義視圖,它執行「嘗試解析它並返回0」操作。

可以LINQ內做到這一點很容易夠對象:

x = orders.Select(y => y.UserDefField) // To just bring down the right values 
      .AsEnumerable() 
      .Sum(text => { 
        int result; 
        // We don't care about the return value... and 
        // it even handles null input. (In any error condition, 
        // "result" will be 0 afterwards.) 
        int.TryParse(text, out result); 
        return result; 
       }); 

...但我真的建議您重溫您的架構,如果你所能。

+1

謝謝@Jon Skeet。我會第一個承認模式是可怕的。但這是我已經處理和期待玩的牌。這是一個超過11年的設計,預計不會很快改變。我會嘗試你的方法。 – FMFF 2012-01-18 21:10:48

1

我會使用聚合函數,像這樣:

var result = orders.Aggregate(new Dictionary<OrderIdType, int>(), (accumulator, item) => { 
    int quantity; 
    if (!int.TryParse(item.USERDEFFIELD, out quantity)) 
     quantity = 0; 
    if (!accumulator.ContainsKey(item.OrderId)) 
     accumulator[item.OrderId] = quantity; 
    else 
     accumulator[item.OrderId] += quantity; 
    return accumulator; 
}); 
+0

已更新,我忘了'int.TryParse' – 2012-01-18 21:18:26