Các đối số DbArithmeticExpression phải có kiểu chung là số


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

Biểu thức Linq này ném ngoại lệ này:

DbArithmeticExpression arguments must have a numeric common type.

Xin vui lòng giúp đỡ!


Kết quả là clientDateTime - o.ClientDateTimeStampgì?
shahkalpesh

noramlly đó phải là một đối tượng của TimeSpan, trong trường hợp ngoại lệ EF được ném.
Nawaz Dhandala

Câu trả lời:


247

Arithmetic with DateTimekhông được hỗ trợ trong Entity Framework 6 trở về trước. Bạn phải sử dụng DbFunctions *. Vì vậy, đối với phần đầu tiên của tuyên bố của bạn, một cái gì đó như:

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

Lưu ý rằng DiffHoursphương thức chấp nhận Nullable<DateTime>.

Thực thể Framwork core (khi được sử dụng với Sql Server, có thể là các nhà cung cấp db khác) hỗ trợ các AddXxxchức năng DateTime (như AddHours). Chúng được dịch sang DATEADDSQL.

* EntityFunctionstrước Entity Framework phiên bản 6.


2

Tôi biết rằng đây là một câu hỏi cũ nhưng trong trường hợp cụ thể của bạn thay vì sử dụng DBFunctionsnhư được đề xuất bởi @GertArnold, bạn không thể đảo ngược phép toán chuyển ra số học được đề cập từ Lambda?

Rốt cuộc clientDateTimetime24là các giá trị cố định nên sự khác biệt của chúng không cần phải được tính toán lại trong mỗi lần lặp.

Giống:

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

Việc tái cấu trúc này thường có thể thực hiện được nếu bạn đang cố gắng so sánh ngày giờ đã lưu được thay đổi bởi một dấu thời gian sửa chữa với một ngày giờ khác.


Tôi đã có tình huống chính xác này, và điều này đã giúp. Tuy nhiên, phạm vi của giải pháp này rất hạn chế đối với một loại vấn đề cụ thể.
Zimano

@Zimano Nó giải quyết vấn đề của OP mà không yêu cầu anh ta thay đổi công nghệ hoặc sử dụng các bản hack. Nếu nó có thể được cấu trúc lại như thế này thì hãy làm điều đó, nếu không thì hãy làm như trong câu trả lời được chấp nhận.
SoonDead

1

Theo cách khác, nếu hiệu suất không phải là mục tiêu thực sự, bạn có thể thử sử dụng AsEnumerable(). Vì vậy, nó sẽ giống như

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

Thêm AsEnumerable () sẽ chuyển truy vấn SQL thành thực thể và cho phép chạy các hàm .Net trên chúng. Để biết thêm thông tin, hãy kiểm tra tại đây về AsEnumerable

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.