識別子dbを使用するので、dbはDbContextであると仮定します。これは、linqステートメントがデータベースサーバー側のSQLで実行され、メモリ内では実行されないことを意味します(使用しているDBのタイプに応じて、SQLなど)。
デバッガでステートメントのタイプをチェックすると、IQueryableまたはIEnumerableですか? IQueryablesはデータベースサーバーによって実行され、IEnumerableは通常あなたのメモリ内で実行されます。通常、データベースサーバはlinq文をあなたより速く、より効率的に実行できるので、linq文がIQueryableであることを確認することをお勧めします。
ただし、データベースサーバはクラス、関数、.NETのいずれも知らないという欠点があります。したがって、IQueryablesではかなり単純な計算しか使用できません。あなたが本当にあなたの声明にAsEnumerable()
を追加し、あなたのLINQ文のどこか途中でいくつかの地元の関数を呼び出す必要がある場合
:
var myLinqResult = db. ... // something IQueryable
.Where(item => ...) // simple statement: still IQueryable
.Select(item => ...) // still simple, still IQueryable
// now you want to call one of your own functions:
.AsEnumerable()
.Select(item => myOwnLocalFunctions(item));
は、実行するローカル機能がConvert.ToDoubleあるstackoverflow: Difference between IQueryable and IEnumerable
を参照してください。 IQueryableはConvertクラスを知らないため、IQueryableとしての機能を実行できません。 AsEnumerable
はこの問題を解決します。
ただし、この場合はAsEnumerableの使用をお勧めしません。データベース上でlinq文を実行するときは、できるだけローカルクラスと関数呼び出しを使わないようにしてください。 Convert.ToDouble
の代わりに(double)x.Sum_Amount
を使用してください。 linq-to-sqlトランスレータ(または類似のデータベース言語コンバータ)は、これをIQueryableとしてどのように変換するかを知っています。
DateTimeの計算やストリング逆のようなSQLに相当する計算がいくつかあります。あなたがローカルメモリにDateTime.AddDays(1)のようなことをしなければならないのなら、それは完璧なSQL同等品があるのは残念です。これは、ローカル機能の後に結合、選択、またはグループ化が必要な場合は特に問題になります。データベースサーバーは、これらの作業をより効率的に行うことができます。幸いにも、IQueryable拡張関数がいくつかあります。それらは見つけることができますSystem.Data.Entity.DbFunctions
エラーから、ダブルに変換している変数の1つがすでにDB内にあるように聞こえます –
lum_sum_amountのいずれかがヌルである可能性がありますか? – BugFinder
私はラムダでConcert.ToDoubleを使用することはできません。それはsfでSQLに解析されます。 ToListを使ってリストを取得しようとすることができます(whereはSQLを実行します)。そしてリストのselectメソッドを使用します。 –