2016-10-02 16 views
6

Tôi có truy vấn LINQ này với Entity Framework 6:Làm thế nào để chuyển đổi DateTime để TimeSpan trong Entity Framework truy vấn

var timeCapturesQuery = Context.TimeCaptures 
    .Where(t => 
     && t.StartDateTime.TimeOfDay < endTime 
     && t.EndDateTime.TimeOfDay > startTime); 

EndTime và StartTime là parmeters loại TimeSpan, StartDateTime và EndDateTime là cột trên bảng datetime.

Đáng tiếc là tôi nhận được lỗi này khi nó được chạy:

Các loại quy định thành viên 'TimeOfDay' không được hỗ trợ trong LINQ to Entities. Chỉ các trình khởi tạo, thành viên thực thể và thuộc tính điều hướng thực thể mới được hỗ trợ.

Làm thế nào tôi có thể nhận được một TimeSpan từ một DateTime (ví dụ: các time từ datetime trong SQL) trong truy vấn LINQ này?

+0

Xin lỗi nhưng tôi không thấy làm thế nào mà có thể giúp đỡ. Bạn đang chuyển đổi DateTime thành một chuỗi sau đó quay trở lại một DateTime sau đó gọi thuộc tính mà ném lỗi. Cũng nên nhớ rằng StartDateTime là một cột trên một bảng, không phải là một tham số. –

+0

Những gì Paul [đã nói] (http://stackoverflow.com/questions/32756662/timeofday-is-not-supported-in-linq-to-entities-find-total-seconds-in-linq-2) có thể hoạt động. – Berkay

+1

Điều gì về [Giải pháp] này (http://stackoverflow.com/a/21289257/5460854) – CodeMaster

Trả lời

3

Hình như DbFunctions.CreateTime là những gì bạn đang tìm kiếm:

Khi được sử dụng như một phần của LINQ to Entities truy vấn, phương pháp này bạn sẽ thấy kinh điển chức năng CreateTime EDM để tạo ra một đối tượng TimeSpan mới .

Vì vậy, để có được kết quả giữa hai lần, bạn có thể:

var timeCapturesQuery = Context.TimeCaptures 
    .Where(t => DbFunctions.CreateTime(t.StartDateTime.Hour, t.StartDateTime.Minute, t.StartDateTime.Second) < endTime && 
     DbFunctions.CreateTime(t.EndDateTime.Hour, t.EndDateTime.Minute, t.EndDateTime.Second) > startTime); 
0

Có vẻ như Linq2db hỗ trợ nó.

https://github.com/linq2db/linq2db/blob/1ff760181717c73859ab3a5519f76943241d460f/Source/Linq/Expressions.cs

Tất nhiên nó không phải là một lựa chọn rất tốt để sử dụng ORM mới.
Nhưng tôi nghĩ đó là phần yếu nhất của EF sau buổi biểu diễn.
Vì vậy, có lẽ đây là thời điểm tốt để suy nghĩ lại.

Với Linq2db bạn có thể cung cấp logic SQL tùy chỉnh (bạn cần tạo biểu thức riêng). Nó không bao giờ cần thiết cho tôi, nhưng bạn có thể đọc this để biết thêm chi tiết.

+0

Chuyển đổi khỏi EF không phải là một lựa chọn. –

2

Thuộc tính TimeOfDay không được hỗ trợ trong LINQ to Entities để bạn có thể thử sử dụng phương pháp SqlFunctions.DatePart để thay thế.

Bạn có lẽ cũng nên chuyển đổi TimeSpans của bạn thành DateTimes.

Tôi nghĩ rằng điều này sẽ làm việc (giả sử các timespans là từ sự khởi đầu của một ngày):

var now = DateTime.Now; 
var today = new DateTime(now.Year, now.Month, now.Day); 

var endDateTime = today + endTime; 
var startDateTime = today + startTime 

var timeCapturesQuery = Context.TimeCaptures.Where(t => 
          SqlFunctions.DatePart("timeofday", t.StartDateTime) < SqlFunctions.DatePart("timeofday", endDateTime) 
          && SqlFunctions.DatePart("timeofday", t.EndDateTime) > SqlFunctions.DatePart("timeofday", startDateTime)); 

Sửa

Như đã đề cập trong các ý kiến ​​các TimeOfTheDay tài sản cụ thể không được hỗ trợ trong phương pháp DATEPART .

lẽ EntityFunctions.DiffNanoseconds phương pháp sẽ làm việc:

var now = DateTime.Now; 
var today = new DateTime(now.Year, now.Month, now.Day); 

var endDateTime = today + endTime; 
var startDateTime = today + startTime 

var timeCapturesQuery = Context.TimeCaptures.Where(t => 
          EntityFunctions.DiffNanoseconds(t.StartDateTime, endDateTime).Value < 0 
          && EntityFunctions.DiffNanoseconds(t.EndDateTime, startDateTime).Value > 0); 

Edit2

Một tùy chọn khác là đơn giản hơn nhiều và tôi nghĩ sẽ làm việc chỉ là để so sánh DateTimes.

Chúng tôi đã chuyển đổi TimeSpans thành DateTimes và chúng ta có thể tạo điều kiện đơn giản bằng LINQ to Entities và nó sẽ hoạt động vì chúng tôi không sử dụng bất kỳ thuộc tính DateTimes nào.

var now = DateTime.Now; 
var today = new DateTime(now.Year, now.Month, now.Day); 

var endDateTime = today + endTime; 
var startDateTime = today + startTime 

var timeCapturesQuery = Context.TimeCaptures.Where(t => t.StartDateTime < endDateTime && t.EndDateTime > startDateTime); 
+0

Không có đối số "thời gian trong ngày" cho DATEPART. –

+0

Vui lòng tham khảo chỉnh sửa của tôi. – YuvShap

Các vấn đề liên quan