2010-11-10 47 views
85

Trong ứng dụng của tôi, tôi đang sử dụng Khung thực thể.LINQ to EntityFramework DateTime

Bảng My

-Article 
-period 
-startDate 

tôi cần hồ sơ phù hợp =>DateTime.Now > startDate and (startDate + period) > DateTime.Now

Tôi đã thử mã này nhưng bây giờ nó làm việc

Context.Article 
    .Where(p => p.StartDate < DateTime.Now) 
    .Where(p => p.StartDate.AddDays(p.Period) > DateTime.Now) 

Khi tôi chạy mã của tôi ngoại lệ sau đây xảy ra

LINQ to Entities does not recognize the method 'System.DateTime AddDays(Double)' method, and this method cannot be translated into a store expression.

+0

Loại nào là 'khoảng thời gian'? 'AddDays' là hàm sai nếu nó là' double'. –

+0

loại thời gian là int – Yucel

Trả lời

160

Khi sử dụng LINQ to Entity Framework, các biến vị ngữ của bạn bên trong mệnh đề Where được dịch sang SQL. Bạn nhận được lỗi đó bởi vì không có bản dịch cho SQL cho DateTime.Add() có ý nghĩa.

Một công việc xung quanh nhanh chóng sẽ được đọc kết quả đầu tiên ở đâu tuyên bố vào bộ nhớ và sau đó sử dụng LINQ to Objects để kết thúc lọc:

Context.Article.Where(p => p.StartDate < DateTime.Now) 
       .ToList() 
       .Where(p => p.StartDate.AddDays(p.Period) > DateTime.Now); 

Bạn cũng có thể thử phương pháp EntityFunctions.AddDays nếu bạn sử dụng .NET 4.0:

Context.Article.Where(p => p.StartDate < DateTime.Now) 
       .Where(p => EntityFunctions.AddDays(p.StartDate, p.Period) 
        > DateTime.Now); 

Lưu ý: Trong EF 6 giờ là System.Data.Entity.DbFunctions.AddDays.

+32

Đây là một công việc nguy hiểm xung quanh, điều gì sẽ xảy ra nếu ToList() trả về một lượng lớn dữ liệu? –

+0

@Stefan P. - Sau đó, câu lệnh đầu tiên sẽ đọc một lượng lớn dữ liệu vào bộ nhớ. Phương pháp thứ hai là tốt, nhưng nó chỉ có sẵn với .NET 4.0. –

+6

Cảm ơn lời khuyên EntityFunctions.AddDays Tôi đang sử dụng EF .net 4.0 nhưng tôi không biết về EntityFunctions, sẽ nhìn vào nó. –

3

Làm thế nào về trừ đi 2 ngày kể từ DateTime.Now:

Context.Article 
.Where(p => p.StartDate < DateTime.Now) 
.Where(p => p.StartDate > DateTime.Now.Subtract(new TimeSpan(2, 0, 0, 0))) 

Thành thật mà nói, tôi không chắc chắn những gì bạn đang cố gắng để đạt được, nhưng điều này có thể làm việc

+0

Các bài viết sẽ bắt đầu được hiển thị vào ngày Bắt đầu và kết thúc sau ngày x (khoảng thời gian). Đây là những gì tôi đang cố gắng làm. Giải pháp thứ hai của Justin Niessner hoạt động rất tốt cho những gì tôi muốn xem – Yucel

+1

Tôi gặp lỗi tương tự khi sử dụng Subtract! –

71

Tôi nghĩ rằng đây là những gì mà cuối cùng câu trả lời đang cố gắng đề nghị, nhưng thay vì cố gắng để thêm ngày để p.startdat (một cái gì đó mà không thể được chuyển đổi sang một tuyên bố sql) tại sao không làm một cái gì đó có thể được tương đương với sql:

var baselineDate = DateTime.Now.AddHours(-24); 

something.Where(p => p.startdate >= baselineDate) 
+7

Đây là câu trả lời tốt hơn nhiều so với câu trả lời được chấp nhận với nhiều phiếu bầu hơn. Nó đơn giản hơn, an toàn hơn và hiệu quả hơn. –

+1

@Adrian Carr - Nó có thể tốt hơn cho trường hợp sử dụng này nhưng không cho nhiều như giải pháp 'EntityFunctions'. Ở đây, toán hạng thứ hai không được lấy từ một thực thể khác trong truy vấn và có thể được tính toán trước khi truy vấn. Nếu cả hai toán hạng được tìm thấy trong db, thì giải pháp 'EntityFunctions' sẽ vẫn phù hợp trong khi giải pháp của phản hồi này sẽ không hoạt động nữa. –

1

Nếu bạn cần biểu thức của mình được dịch sang SQL, bạn có thể thử sử dụng phương thức

System.Data.Entity.Core.Objects.AddDays .

Thực ra đã được đánh dấu lỗi thời nhưng nó hoạt động. Nó phải được thay thế bằng System.Data.Entity.DbFunctions.AddDays nhưng tôi không thể tìm thấy nó ...

+0

Điều này không có gì nhiều hơn câu trả lời được chấp nhận từ 4 năm trước! –

+0

@AndrewHarris cũng câu trả lời của tôi là 4 năm trước câu trả lời. Trong phiên bản đầu tiên của câu trả lời có một ToList (=> dữ liệu hóa) trước khi ở đâu (xem bình luận đầu tiên của câu trả lời). – bubi