1. ホーム
  2. c#

[解決済み] マテリアライズされた値が NULL であるため、値型 'Int32' へのキャストに失敗しました。

2022-04-12 05:50:07

質問

次のようなコードがあります。エラーが発生します。

実体化された値が NULL であるため、値型 'Int32' へのキャストに失敗しました。結果型の汎用パラメータまたはクエリが null 可能な型を使用する必要があります。

CreditHistory テーブルにレコードがない場合。

var creditsSum = (from u in context.User
                  join ch in context.CreditHistory on u.ID equals ch.UserID                                        
                  where u.ID == userID
                  select ch.Amount).Sum();

ヌル値を受け入れるようにクエリを変更するにはどうすればよいですか?

どのように解決するのですか?

linq-to-sqlクエリは、コードとして実行されるのではなく、SQLに変換されます。時には、これは予期せぬ振る舞いをもたらす、quot;リーキー・アブストラクション(leaky abstraction")です。

そのひとつがNULLの処理で、予期しないNULLがさまざまな場所に存在することがあります。 ...DefaultIfEmpty(0).Sum(0) はこの(非常に単純な)ケースで役に立ちます。 SUMnull c#は0を期待するのに対し

より一般的な方法として ?? に翻訳されます。 COALESCE 生成されたSQLが予期せぬNULLを返す危険性がある場合は、いつでもそうします。

var creditsSum = (from u in context.User
              join ch in context.CreditHistory on u.ID equals ch.UserID                                        
              where u.ID == userID
              select (int?)ch.Amount).Sum() ?? 0;

これは、最初に int? を返すことができることをC#コンパイラに伝えます。 null であるにもかかわらず Sum()int . 次に、通常の ?? 演算子で処理します。 null の場合です。

この回答を元に、私が書いた ブログ記事 LINQ to SQLとLINQ to Entitiesの両方についての詳細が書かれています。