Argumen DbArithmeticExpression harus memiliki tipe umum numerik


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(); 

Ekspresi Linq ini memunculkan pengecualian ini:

DbArithmeticExpression arguments must have a numeric common type.

Tolong bantu!


Apa hasil dari clientDateTime - o.ClientDateTimeStamp?
shahkalpesh

noramlly yang harus menjadi objek dari TimeSpan, dalam pengecualian EF dilemparkan.
Nawaz Dhandala

Jawaban:


247

Aritmatika dengan DateTimetidak didukung di Entity Framework 6 dan sebelumnya. Anda harus menggunakan DbFunctions *. Jadi, untuk bagian pertama dari pernyataan Anda, seperti:

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

Perhatikan bahwa DiffHoursmetode menerima Nullable<DateTime>.

Inti Entity Framwork (bila digunakan dengan Sql Server, mungkin penyedia db lain) mendukung AddXxxfungsi DateTime (seperti AddHours). Mereka diterjemahkan ke DATEADDdalam SQL.

* EntityFunctionssebelum Entity Framework versi 6.


2

Saya tahu bahwa ini adalah pertanyaan lama tetapi dalam kasus khusus Anda alih-alih menggunakan DBFunctions seperti yang disarankan oleh @GertArnold, tidak bisakah Anda membalikkan operasi, memindahkan aritmatika yang dimaksud dari Lambda?

Toh clientDateTimedan time24merupakan nilai fix sehingga perbedaannya tidak perlu dihitung ulang di setiap iterasi.

Suka:

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();

Refactor ini biasanya dapat dilakukan jika Anda mencoba membandingkan datetime yang disimpan yang digeser oleh stempel waktu tetap dengan datetime lainnya.


Saya mengalami situasi yang persis seperti ini, dan ini membantu. Namun, cakupan solusi ini sangat terbatas pada jenis masalah tertentu.
Zimano

@Zimano Ini memecahkan masalah OP tanpa mengharuskannya mengubah teknologi atau menggunakan peretasan. Jika bisa direfraktor seperti ini maka lakukan, jika tidak lakukan seperti dalam jawaban yang diterima.
SoonDead

1

Sebaliknya, jika kinerja bukanlah tujuan yang sebenarnya, Anda dapat mencoba menggunakan AsEnumerable(). Jadi, akan seperti itu

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

Menambahkan AsEnumerable () akan mengonversi kueri SQL menjadi entitas dan memungkinkan untuk menjalankan fungsi .Net pada kueri tersebut. Untuk info lebih lanjut, lihat di sini tentang AsEnumerable

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.