2009-02-20 52 views
55

Tôi đang cố xác định số ngày giữa 2 ngày sử dụng LINQ với Entity Framework. Đó là nói với tôi rằng nó không công nhận Subtract trên lớp System.TimeSpanLINQ to Entities để trừ 2 ngày

Đây là phần của tôi trong truy vấn LINQ.

where ((DateTime.Now.Subtract(vid.CreatedDate).TotalDays < maxAgeInDays)) 

Đây là lỗi tôi nhận được trong debugger VS.NET

{ "LINQ to Entities không nhận ra phương pháp 'System.TimeSpan Subtract (System.DateTime)' phương pháp, và điều này phương pháp không thể được dịch sang biểu thức cửa hàng. "}

Tôi có làm gì sai hoặc có cách nào tốt hơn để lấy số ngày giữa 2 DateTimes trong khuôn khổ thực thể?

nhờ Michael

+0

Tôi cũng đã cố gắng tránh timespan bằng cách thay đổi công thức một chút thành những điều sau đây - mà vẫn không hoạt động trong đó (vid.CreatedDate.AddDays (maxAgeInDays)> = DateTime.Now) –

Trả lời

41

Dưới đây là cách tôi đã nhận nó làm việc

tôi định nghĩa một biến datetime mà đại diện cho ngày lâu đời nhất

DateTime oldestDate = DateTime.Now.Subtract(new TimeSpan(maxAgeInDays, 0, 0, 0, 0)); 
... 

sau đó tôi sửa đổi phần nơi của truy vấn LINQ

where (vid.CreatedDate >= oldestDate) 

làm việc như một sự quyến rũ - cảm ơn Micah vì đã khiến tôi suy nghĩ về cây biểu hiện

+2

Bạn phải gắn cờ @Micah làm câu trả lời và thêm nhận xét vào câu trả lời của mình hoặc cập nhật câu hỏi của bạn bằng câu trả lời cuối cùng. – ongle

+0

Thông minh, khéo léo thông minh. Đơn giản và thẳng về phía trước. Tôi vẫn tự hỏi tại sao nó không đến với tôi ngay từ đầu. Cảm ơn bạn đã chia sẻ –

11

Bạn chạy vào các loại isses vì ​​vị cần phải được dịch sang một cây biểu thức. Và quá trình dịch không nhận ra phương thức DateTime.Now.Subtract.

+0

vẫn có cách để làm gì Tôi đang cố gắng làm như vậy mà tôi có thể được dịch sang một cây biểu hiện? –

1

Thực tế là theo thiết kế, LINQ to Entities cần dịch toàn bộ truy vấn sang câu lệnh SQL. Đó là nơi mà nó không thể nhận ra phương thức Trừ. Nó sẽ xảy ra bất cứ khi nào bạn cố gắng sử dụng phương thức C#/VB bên trong một truy vấn. Trong những trường hợp này, bạn phải tìm ra cách để đưa ra phần đó từ truy vấn. bài này giải thích thêm một chút: http://mosesofegypt.net/post/LINQ-to-Entities-what-is-not-supported.aspx

+0

Câu trả lời này là đúng, nhưng chắc chắn không phải là câu trả lời tôi muốn. LINQ to SQL hỗ trợ gọi các phương thức bên ngoài nhiều như bạn thích, vì vậy sự cân bằng này là không may. –

+2

liên kết đã chết. – Bijan

90

Câu trả lời được chấp nhận là tốt hơn trong trường hợp này, nhưng để tham khảo bạn có thể sử dụng lớp EntityFunctions để thực hiện các hoạt động vào những ngày, trong số những thứ khác.

where (vid.CreatedDate >= EntityFunctions.AddDays(DateTime.Now, -maxAgeInDay)) 
+0

Cảm ơn, đây chính xác là những gì tôi đang tìm kiếm. – wdanda

+3

Lưu ý rằng điều này chỉ được hỗ trợ trong Entity Framework v4. Điều này sẽ không hoạt động đối với Entity Framework v1. –

+0

Cảm ơn bạn đã chia sẻ lớp EntityFunctions. Rất hữu ích – StackThis

18

Bạn cũng có thể sử dụng System.Data.Objects.EntityFucntions:

currentDate = DateTime.Now; 

... 
where EntityFunctions.DiffDays(currentDate, vid.CreatedDate) < maxAgeIdDays 

Tất cả các chức năng từ EntityFunctions chỉ dành cho LINQ-to-đơn vị và được ánh xạ tới các chức năng SQL.

+0

Chúng cũng hoạt động cho LINQ to Entities. –

+0

@Morten: Đó là loại, chúng chỉ hoạt động với LINQ-to-entity. –

+0

Nhiều chức năng cụ thể của SQL Server có sẵn thông qua lớp 'System.Data.Objects.SqlClient.SqlFunctions'. Tất nhiên, kho dữ liệu phải là một SQL Server để làm việc này. Thông tin thêm: http://msdn.microsoft.com/en-us/library/system.data.objects.sqlclient.sqlfunctions.aspx – bernhof

0

Bạn có thể xác định tài sản mới trong mô hình của bạn:

public DateTime StartDate{ get; set; } 
    public DateTime EndDate{ get; set; } 
    public TimeSpan CalculateTime{ 
     get 
     { 
      return EndDate.Subtract(StartDate); 
     } 
    } 

Bây giờ, bạn có thể sử dụng một cái gì đó như thế:

var query = from temp in db.Table 
select new MyModel { 
    Id = temp.Id, 
    Variable1 = temp.Variable1, 
    ... 
    EndDate = temp.EndDate, 
    StartDate = temp.StartDate 
} 

Khi bạn có nhìn vào kết quả, bạn có thể sử dụng trở lại như:

return query 

Bây giờ, trong truy vấn, chúng tôi có CalculateTime (trừ giữa EndDate và Startdate).

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