DbArithmeticExpression引数には、共通の数値型が必要です


120
TimeSpan time24 = new TimeSpan(24, 0, 0);
TimeSpan time18 = new TimeSpan(18, 0, 0);    

// first get today's sleeping hours
List<Model.Sleep> sleeps = context.Sleeps.Where(
    o => (clientDateTime - o.ClientDateTimeStamp < time24) && 
          o.ClientDateTimeStamp.TimeOfDay > time18 && 
          clientDateTime.TimeOfDay < time18 && 
          o.UserID == userid).ToList(); 

このLinq式は次の例外をスローします。

DbArithmeticExpression arguments must have a numeric common type.

助けてください!


の結果はclientDateTime - o.ClientDateTimeStamp何ですか?
shahkalpesh 2012年

通常、これはTimeSpanのオブジェクトである必要があります。EFでは例外がスローされます。
Nawaz Dhandala、2012年

回答:


247

算術with DateTimeは、Entity Framework 6以前ではサポートされていません。DbFunctions * を使用する必要があります。したがって、ステートメントの最初の部分では、次のようになります。

var sleeps = context.Sleeps(o =>
    DbFunctions.DiffHours(o.ClientDateTimeStamp, clientDateTime) < 24);

DiffHoursメソッドはを受け入れることに注意してくださいNullable<DateTime>

Entity Framworkコア(Sql Serverで使用される場合、おそらく他のdbプロバイダー)は、DateTime AddXxx関数(などAddHours)をサポートします。DATEADDSQLに変換されます。

* EntityFunctionsEntity Frameworkバージョン6より前。


2

私はこれが古い質問であることを知っていますが、特定のケースではDBFunctions@GertArnoldによって提案されているように使用する代わりに、問題の算術演算をLambdaから削除する操作を反転できませんか?

結局のところclientDateTimetime24値は修正されているので、それらの差はすべての反復で再計算する必要はありません。

お気に入り:

TimeSpan time24 = new TimeSpan(24, 0, 0);
TimeSpan time18 = new TimeSpan(18, 0, 0);    

var clientdtminus24 = clientDateTime - time24;

// first get today's sleeping hours
List<Model.Sleep> sleeps = context.Sleeps.Where(
    o => (clientdtminus24 < o.ClientDateTimeStamp) && 
          o.ClientDateTimeStamp.TimeOfDay > time18 && 
          clientDateTime.TimeOfDay < time18 && 
          o.UserID == userid).ToList();

このリファクタリングは、固定タイムスタンプによってシフトされて保存された日時を他の日時と比較しようとする場合に通常可能です。


私はこの正確な状況にあり、これが助けになりました。ただし、このソリューションの範囲は、特定の種類の問題に非常に限定されています。
ジマーノ

@Zimanoテクノロジを変更したり、ハックに頼ったりすることなく、OPの問題を解決します。このようにリファクタリングできる場合はそれを行い、できない場合は受け入れられた回答のようにしてください。
SoonDead

1

逆に、パフォーマンスが真の目標でない場合は、を使用してみてくださいAsEnumerable()。だから、それは

List<Model.Sleep> sleeps = context.Sleeps.AsEnumerable().Where(....

AsEnumerable()を追加すると、SQLクエリがエンティティに変換され、それらに対して.Net関数を実行できます。詳しくは、AsEnumerableについてこちらをご覧ください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.