2010-11-03 15 views
8

Con Linq to Entities, intento consultar una tabla de registro para buscar filas cerca de una fila coincidente. Tengo problemas para agregar una fecha dentro de la consulta. Esto es lo que tengo hasta ahora.Agregue una fecha en Linq a entidades

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 

Dejando de lado la condición de "lo que sea" que encuentra la fila que estoy interesado, "twoHours" ha sido variablemente un lapso de tiempo, una función .AddHours() y así sucesivamente. No he encontrado la manera correcta de que EF pueda generar SQL que agregue el valor de un campo (coincidencia.Tiempo) a una constante.

La solución obvia es hacer primero la consulta de "coincidencia" y luego usar el valor literal en una segunda consulta, pero he simplificado el ejemplo de código aquí al problema principal (agregando fechas en la consulta) y en realidad mi consulta es más compleja y esto no sería ideal.

Saludos

+0

he tenido un problema similar. El problema es que .AddHours() no tiene un equivalente SQL, y por lo tanto, Linq no puede convertir eso a una expresión SQL. He superado esto invocando la ejecución retrasada llamando a .ToList() y luego aplicando su filtro .AddHours() en una colección en memoria. – dotariel

+0

@ XSaint32, eso está doblemente mal. There * is * [a (T) SQL equivalent,] (http://msdn.microsoft.com/en-us/library/ms186819.aspx) y usted * puede * llamarlo desde el EF. –

+0

@Craig - Gracias por la entrada. No estaba enterado de eso. – dotariel

Respuesta

11

Puede generar un AddHours utilizando el EntityFunctionsclass.

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

Sin embargo, no espere que este WHERE a ser optimizado con un índice a menos que tenga un índice de expresión en la columna.

+0

Impresionante, gracias Craig –

+0

Nota, 'EntityFunctions' ha sido marcado como obsoleto. Utilice la clase de reemplazo 'DbFunctions' en el espacio de nombres' System.Data.Entity' en su lugar. – Amasa

3

EntityFunctions está en desuso en favor de 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

... si estás en EF 6 o posterior ... –