Entity FrameworkがRecordsのnullでMAXを呼び出す

entity-framework

質問

IQueryableでMax()を呼び出したときにゼロレコードがあると、次の例外が発生します。

マテリアライズド値がnullであるため、値型 'Int32'へのキャストが失敗しました。結果タイプの総称パラメーターまたは照会は、NULL可能タイプを使用しなければなりません。

var version = ctx.Entries
    .Where(e => e.Competition.CompetitionId == storeCompetition.CompetitionId)
    .Max(e => e.Version);

なぜ私はこれが起こるのか理解しています私の質問は、テーブルが空になる可能性がある場合にこれを行うための最善の方法であることです。以下のコードはこの問題を解決しますが、MaxOrDefault()という概念はありません。

int? version = ctx.Entries
    .Where(e => e.Competition.CompetitionId == storeCompetition.CompetitionId)
    .Select(e => (int?)e.Version)
    .Max();

受け入れられた回答

はい、TのNullableへのキャストは、LINQ to Entitiesクエリの問題に対処するための推奨される方法です。正しいシグネチャを持つMaxOrDefault()メソッドを持つことは面白い考えのように思えますが、この問題を提示するそれぞれのメソッドに対して追加のバージョンが必要になるだけで、それほど拡張性がありません。

これは、CLRでの動作とデータベースサーバーでの実際の動作との間の多くの不一致の1つです。 Max()メソッドのシグネチャは、結果の型がCLRの入力型とまったく同じであることが期待されるため、この方法で定義されています。しかしデータベースサーバでは結果はnullになる可能性があります。そのため、入力を(NulllableのTに)キャストする必要があります(クエリの作成方法によって異なりますが)。

これがあなたが上に持っているものよりわずかに簡単に見える解決策です:

var version = ctx.Entries 
    .Where(e => e.Competition.CompetitionId == storeCompetition.CompetitionId) 
    .Max(e =>(int?)e.Version);

お役に立てれば。


人気のある回答

これを試して最大のデフォルトを作成してください。

int version = ctx.Entries 
    .Where(e => e.Competition.CompetitionId == storeCompetition.CompetitionId) 
    .Max(e =>(int?)e.Version) ?? 0;


ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ
ライセンスを受けた: CC-BY-SA with attribution
所属していない Stack Overflow
このKBは合法ですか? はい、理由を学ぶ