2010-11-03 44 views
8

Với LINQ to Entities, tôi đang cố truy vấn bảng Nhật ký để tìm các hàng gần một hàng phù hợp. Tôi gặp sự cố khi thêm ngày bên trong truy vấn. Đây là những gì tôi có cho đến nay.Thêm ngày trong LINQ vào đối tượng

from 
    l in objectSet.Logs 
let 
    match = objectSet.Logs.Where(whatever).FirstOrDefault() 
where 
     l.Timestamp > (match.Timestamp - twoHours) 
    && l.Timestamp < (match.Timestamp + twoHours) 
select 
    l 

Rời ra "bất cứ điều gì" điều kiện tìm thấy hàng Tôi quan tâm đến, "twoHours" đã variably được một khoảng thời gian, một chức năng .AddHours() và vân vân. Tôi đã không tìm thấy đúng cách mà EF có thể tạo ra SQL mà thêm giá trị từ một trường (match.Timestamp) vào một hằng số.

Giải pháp hiển nhiên là thực hiện truy vấn "khớp" trước rồi sử dụng giá trị bằng chữ trong truy vấn thứ hai, nhưng tôi đã đơn giản hóa ví dụ mã ở đây thành vấn đề chính (thêm ngày trong truy vấn) và thực tế truy vấn của tôi phức tạp hơn và điều này sẽ không lý tưởng.

Cheers

+0

Tôi đã có một vấn đề tương tự. Vấn đề là .AddHours() không có một SQL tương đương, và do đó, LINQ không thể chuyển đổi nó thành một biểu thức SQL. Tôi đã khắc phục điều này bằng cách gọi thực thi bị trì hoãn bằng cách gọi .ToList() và sau đó áp dụng bộ lọc .AddHours() của bạn trên một bộ sưu tập trong bộ nhớ. – dotariel

+0

@ XSaint32, đó là sai hai lần. Có * là * [a (T) SQL tương đương,] (http://msdn.microsoft.com/en-us/library/ms186819.aspx) và bạn * có thể * gọi nó từ EF. –

+0

@Craig - Cảm ơn bạn đã nhập. Tôi đã không nhận thức được điều đó. – dotariel

Trả lời

11

Bạn có thể tạo một AddHours sử dụng EntityFunctionsclass.

from 
    l in objectSet.Logs 
let 
    match = objectSet.Logs.Where(whatever).FirstOrDefault() 
where 
     (l.Timestamp > EntityFunctions.AddHours(match.Timestamp, -1 * twoHours)) 
    && // ... 
select 
    l 

Tuy nhiên, tôi không mong đợi này WHERE được tối ưu hóa với một chỉ số trừ khi bạn có một chỉ số biểu hiện trên cột.

+0

Tuyệt vời, cảm ơn Craig –

+0

Lưu ý, 'EntityFunctions' đã được đánh dấu là lỗi thời. Sử dụng lớp thay thế 'DbFunctions' trong không gian tên' System.Data.Entity' để thay thế. – Amasa

3

EntityFunctions được phản đối ủng hộ DbFunctions

public int GetNumUsersByDay(DateTime Date) 
     { 
      using (var context = db) 
      { 
       var DateDay = new DateTime(Date.Year, Date.Month, Date.Day); 
       var DateDayTomorrow = DateDay.AddDays(1); 
       return context.Users.Where(m => DbFunctions.AddHours(m.DateCreated,-5) >= DateDay && m.DateCreated < DateDayTomorrow).Count(); 
      } 
     } 
+0

... nếu bạn đang ở EF 6 trở lên ... –

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