2011-12-29 9 views
12

私がない場合:空のセットの合計がnullであるのはなぜですか?

int updateGamePlays = db.tblArcadeGames.Where(c => c.ParentGameID == GameID).Sum(c => c.Plays); 

レコードがこのクエリで返されていない場合、それはスロー:

のSystem.InvalidOperationException:ヌル値がタイプ可能System.Int32と メンバーに割り当てることができませんnullを許可しない値の型です。

それが0を返すために取得する唯一の方法は、実行している:

int updateGamePlays = db.tblArcadeGames.Where(c => c.ParentGameID == GameID).Sum(c => (int?)c.Plays) ?? 0; 

をデータベースc.Playsでnull非許容intです。

セット理論では、空集合の合計は0ref)に等しくなければなりません。彼らはそれを返すようにLinq-to-SQLにどう入りましたかnull

+4

これはデータベースの数が増え、理論の設定が不十分です。 SQL ServerのNULL可能な列の 'SUM'とは何ですか? – Marc

+0

@Marc質問で問題の列にリンクしていませんNULL可能です –

+1

L2S dbmlはこのデータセットに対してそれを認識していますか?もしそうなら、フィールドは 'int'ではなく' int'であると仮定します。 – Marc

答えて

9

According to a source at Microsoft、空のセットの合計は()ので、それはSQLで動作する方法のnullです:

テーブルは空 - 私はこの例外になっているとき:InvalidOperationExceptionが

InをSQLの場合、Sum()集合演算子は空の集合に対してnullを返します。これは設計通りです。

+16

"... misdesigned。 " – starblue

+1

しかし、空のIEnumerableでSumを使用すると、正しく0が返されるため、MicrosoftはIQueryableのSum()をSQLと一貫性を持たせるように選択しましたが、IEnumerableのSum()と矛盾します。あいまいな選択... – JustAMartin

0

あなたはゼロの種子で、より一般的なAggregate方法を使用することができます。

int updateGamePlays = db.tblArcadeGames 
    .Where(c => c.ParentGameID == GameID) 
    .Aggregate(0, (a, c) => a + c.Plays); 

これがNULL可能なタイプを使用する必要はありません。

+0

LINQ to SQLについてはわかりませんが、LINQ to Entitiesは '集計 'をサポートしていません。 –

2

もう1つの方法は、常に少なくとも1つの値が存在することを確認するために0にセットを追加することです。

int updateGamePlays = db.tblArcadeGames.Where(c => c.ParentGameID == GameID) 
             .Select(c => c.Plays) 
             .Concat(new [] { 0 }) 
             .Sum(); 
関連する問題