2016-01-26 23 views
8

Tôi đang cố gắng so sánh hai số DateTimes xuống phút từ số DateTime.Now và mục nhập SQL. Tôi thấy vấn đề là các ve bị tắt nhẹ do loại được trả về từ DB. Tuy nhiên tôi không thể tìm ra một công việc xung quanh.C# Ngày giờ theo phút từ linq

Đây là tôi DateTime để lấy

DateTime toGrab = DateTime.Now.AddMinutes(10) 
           .AddSeconds(-DateTime.Now.Second)  
           .AddMilliseconds(-DateTime.Now.Millisecond); 

Và có biểu hiện LINQ của tôi.

cc.DBAppointments.Where(c => c.StartDate == toGrab && c.Approved == 1).ToList(); 

Bất kỳ lời khuyên nào?

+2

Bạn đang gọi 'DateTime.Now' nhiều lần, điều này có thể cung cấp cho bạn các kết quả khác nhau. –

Trả lời

6

Tôi sẽ giả sử bạn đang sử dụng Entity Framework cho việc này. Nếu bạn chỉ cần so sánh datetime cho đến phút, bạn có thể sử dụng System.Data.Entity.DbFunctions để truy cập các chức năng chuẩn trong linq-to-entity. Bạn có thể sử dụng ví dụ:

cc.DBAppointments 
    .Where(c => DbFunctions.DiffMinutes(c.StartDate,DateTime.Now) == 0 && c.Approved == 1) 
    .ToList(); 

Bằng cách này bạn có thể truy cập đến nâng cao so sql datetime và bạn không cần phải làm thủ thuật thêm giây/mili giây để DateTime.Now của bạn. Hàm này sẽ bỏ qua mọi thứ nhỏ hơn phút.

+2

Điều này thậm chí còn tinh khiết hơn so với mắt, bởi vì EF dịch 'DateTime.Now' thành hàm s-SQL' SysDateTime() ', do đó so sánh chính xác với thời gian cơ sở dữ liệu thực hiện truy vấn. Về mặt lý thuyết, biến 'DateTime' từ một khách hàng có thể là giây khi nó được đánh giá. Chưa kể đến sự khác biệt (không lý thuyết) giữa đồng hồ máy khách và máy chủ. –

+0

Đó là mẹo tôi luôn quên về các hàm dbfunctions, chỉ cần sửa một tài nguyên nhỏ là System.Data.Entity. – SernOne

+0

@ SernOne Cảm ơn bạn đã chỉ ra rằng, đã chỉnh sửa nó –

1

Thay đổi

DateTime toGrab = DateTime.Now.AddMinutes(10) 
           .AddSeconds(-DateTime.Now.Second) 
           .AddMilliseconds(-DateTime.Now.Millisecond); 

Để

DateTime now = DateTime.Now; 
DateTime toGrab = now.AddMinutes(10) 
        .AddSeconds(-now.Second) 
        .AddMilliseconds(-now.Millisecond); 

Trên một lưu ý khác nhau, là có bất cứ lý do tại sao bạn sẽ cần phải lấy hẹn trong vòng miligiây chính xác? Có vẻ như rất dễ bị mất hồ sơ?

Sửa

Ngoài ra, trong cơ sở dữ liệu của bạn, giá trị 2015-12-10 10:33:48.373 là khác nhau để 2015-12-10 10:33:48.374 mặc dù họ là 1 milisecond ngoài. Nếu bạn muốn có phạm vi rộng hơn, bạn có thể làm c.StartDate >= startDate && c.StartDate <= endDate && c.Approved == 1

+0

Lưu ý rằng điều này vẫn sẽ không cung cấp cho bạn một "đầu của phút" rõ ràng, vì có nhiều chi tiết hơn trong 'DateTime' hơn một phần nghìn giây. –

4

Bạn đang tạo nhiều tham chiếu đến DateTime.Now, có thể có giá trị khác nhau mỗi lần. Sau đây sẽ làm việc tốt hơn:

var now = DateTime.Now; 
var toGrab = now.Date.AddHours(now.Hour).AddMinutes(now.Minute + 10); 

Lưu ý rằng, để có được một "đỉnh phút" rõ ràng, thêm giờ và phút đến một ngày sẽ làm việc tốt hơn so với cố gắng để loại bỏ các giây và mili giây vì có nhiều chi tiết trong một số DateTime hơn mili giây.

1

Bạn có thể làm comparisons on TimeSpan đối tượng, có nghĩa là bạn có thể làm điều đó như thế này:

TimeSpan oneMinute = new TimeSpan(0, 1, 0); 
cc.DBAppointments.Where(c => 
    DateTime.Now.AddMinutes(10).Subtract(c.StartDate) < oneMinute && 
    c.Approved == 1).ToList(); 

Tất nhiên nếu c.StartDateít hơn 9 phút trong tương lai, trừ sẽ có một kết quả của < - 1 phút. Tôi không chắc chắn nếu mục tiêu của bạn là trong vòng 1 phút. Nếu đó là trường hợp, bạn có thể thêm .Duration() để phương trình của bạn, mà sẽ trả lại tuyệt đối giá trị của TimeSpan:

cc.DBAppointments.Where(c => 
    DateTime.Now.AddMinutes(10).Subtract(c.StartDate).Duration() < oneMinute && 
    c.Approved == 1).ToList(); 
Các vấn đề liên quan