2016-01-22 20 views
5

フィールドの合計に基づいてデータベースから返された値を取得しようとしています。MVC linq to sql sum

しかし、このメッセージ取得: マテリアライズド値がnullであるため、値型に

キャストは「System.Decimalの」失敗しました。結果の型の汎用パラメータ またはクエリでは、null可能な型を使用する必要があります。

データベースには、その日のそのユーザーのレコードが含まれていないことが有効です。したがって、null可能なルートを経由しました。古き良き時代には、ISNULLでストアドプロシージャを構築しました!!!

これは私が持っている基本的な表現である:それをグーグルで

decimal? foodCount = dbContext.fad_userFoods.Where(uf => uf.dateAdded == thisDate && uf.userID == thisGuid).Sum(uf=>(decimal?)uf.quantityAmount ?? 0m);

はNULLの定義との使用を思い付きました? "m"は10進数で表示されます。しかし、それでもエラーは続く!

あなたの集団的な助けはこれまでどおり非常に貴重です。前もって感謝します。

答えて

6

DefaultIfEmptyメソッドを使用します。値がまったく見つからない場合は、0が入ります。

decimal foodCount = dbContext.fad_userFoods 
    .Where(uf => uf.dateAdded == thisDate && uf.userID == thisGuid) 
    .Select(uf => uf.quantityAmount) 
    .DefaultIfEmpty() 
    .Sum(); 
+0

ビンゴ!ありがとうMaarten、これはトリックでした。 SQLにlinqを学ぶためにまだたくさん! – stumcc

3

Convert.ToDecimal()を使用すると、nullの問題が処理されます。エンティティへ

decimal foodCount = dbContext.fad_userFoods.Where(uf => uf.dateAdded == thisDate 
                && uf.userID == thisGuid) 
              .Sum(uf=> Convert.ToDecimal(uf.quantityAmount ?? 0m)); 

LINQは、メソッド「System.Decimalの ToDecimal(System.Decimalの)」方法、及びこの方法を認識しない格納式に 翻訳することができません。

編集:

decimal foodCount = dbContext.fad_userFoods.Where(uf => uf.dateAdded == thisDate 
                && uf.userID == thisGuid) 
              .Sum(uf=> { decimal result; 
                 decimal.TryParse(uf.quantityAmount,out result); 
                 return result;}); 
+0

と、このエラーメッセージが表示されます:あなたの場合の第2のアプローチを適用する完全性については

は、基本的にSumコールの?? 0外を移動するだろうLINQ toメソッドはSystem.Decimal ToDecimal(System.Decimal)メソッドを認識せず、このメソッドをストア式に変換することはできません。 – stumcc

+0

@stumcc:私は私の答えを更新しました。 – Prabhat

3

それはsumないaverageですので、あなたが本当にヌル値を気にしませんか? ヌル値を単に削除しないのはなぜですか?

decimal? foodCount = dbContext.fad_userFoods 
     .Where(uf => 
     uf.dateAdded == thisDate && 
     uf.userID == thisGuid && 
     uf.quantityAmount != null) 
     .Sum(uf=> uf.quantityAmount); 
+0

基本的に私は誰かが1日に食べた食べ物を探しています。だから、その人はそれらの食べ物を食べていない可能性があります、したがって、テーブルの上に存在しないので、額の合計は0になります。 – stumcc

+1

はい、この場合、nullは0に変換する必要があります。これは0に変換する必要があります。したがって、where句でそれを除外すると、問題は完全にエスケープされますが、引き続き同じ合計が返されます。また、データベース内の型の変換を回避します。 – smoksnes

2

混乱はエンティティへのLINQでSumがオブジェクトにLINQよりも少し異なって処理されるという事実に由来します。宣言から、decimalが0を返すように見えるが、実際にはSQL関数は、ターゲット列がNULL値ではない場合でもNULLを返します。

これを知ったら、それを解決するには2通りの方法があります。

レッツは、私たちがdecimal列を持つテーブルがあると、元の式が

table.Sum(item => item.Column) 

最初の方法であると言うMaarten answerに含まれるパターンを使用して、それを変換することです:

table.Select(item => item.Column).DefaultIfEmpty().Sum() 

第二の方法があります明示的に非null型を関数内でnullableに変換して適用するヌル集約演算子結果

どちらの方法でも同じ結果が得られますので、あなたの個人的な好みに合ったものを使用してください。私はそれ以前に試みたが、もう一度それをしようとした

decimal foodCount = dbContext.fad_userFoods 
    .Where(uf => uf.dateAdded == thisDate && uf.userID == thisGuid) 
    .Sum(uf => (decimal?)uf.quantityAmount) ?? 0;