trapemiyaの日記

hatenablogが新しくなったんで新規一転また2019年1月からちょこちょこ書いてます。C#中心のプログラミングに関するお話です。

DataTableの設計におけるLINQで集計する列のデータ型

DataTableの列を集計する場合、以下のように書くことが多いと思います。

items[1] = dataTable1.AsEnumerable()
      .Where(p => p.区分 == "予測")
      .Sum(p => p.金額);


この時、個々のレコードの金額はint型を超えることがなくても、Sumした結果がint型を超えると
「算術演算の結果オーバーフローが発生しました。」
というエラーが発生します。
先ほど、このバグ対応をしました。具体的には、金額のint型をdecimal型に変えただけです。
下期になり、通期の金額を合計しようとして桁あふれしてしまったようです。実行時エラーはやっかいですね。
というわけで、LINQで集計するのであれば集計した結果を保持できる型で設計しましょうというお話でした。

でもね、列のデータ型はint型のままとして

      .Sum(p => (decimal)p.金額);

でもいいんだよ。本来はDataTableの列の型がintでいいならintで設計すべきで、LINQでSumに対応するのが正解なんでしょうね。
でも、いつかこのアプリを改修した際に、また以下のようにdecimalを付け忘れてしまうかもしれない。
そうするといつかまた実行時エラーが出てしまう。それが嫌だったんでDataTable側で対応しちゃいました。

      .Sum(p => p.金額);

本来はそうかもしれない。でも、リスクなど総合的に考えた時、本来の道を行かないことだってあるのかなーと。

いずれにしても実行時エラーになりやすいんで気を付けましょうね。(自戒)