2012-03-08 14 views

Respuesta

54

sólo tiene que utilizar la propiedad Date:

var today = DateTime.Today; 

var q = db.Games.Where(t => t.StartDate.Date >= today) 
       .OrderBy(t => t.StartDate); 

en cuenta que yo he evaluado de forma explícita DateTime.Todayvez por lo que la consulta es consistente - de lo contrario cada vez que se ejecuta la consulta, e incluso dentro de la ejecución , Today podría cambiar, por lo que obtendría resultados inconsistentes. Por ejemplo, supongamos que tiene los datos de:

Entry 1: March 8th, 8am 
Entry 2: March 10th, 10pm 
Entry 3: March 8th, 5am 
Entry 4: March 9th, 8pm 

Seguramente ya sea ambas entradas 1 y 3 deben estar en los resultados, o ni de ellos debería ... pero si se evalúa DateTime.Today y TI cambios al 9 de marzo después de que se lleva a cabo las dos primeras comprobaciones, que podría terminar con las entradas 1, 2, 4.

por supuesto, el uso de DateTime.Today asume usted está interesado en la fecha de la zona horaria local de . Eso puede no ser apropiado, y usted debe hacer absolutamente, seguro que sabe lo que quiere decir. Usted puede querer usar DateTime.UtcNow.Date en su lugar, por ejemplo. Desafortunadamente, DateTime is a slippery beast ...

EDITAR: Quizás desee deshacerse de las llamadas a DateTime propiedades estáticas en general, hacen que el código sea difícil de probar. En Noda Time tenemos una interfaz específicamente para este propósito (IClock) que esperamos que se inyecte de forma adecuada. Hay una implementación de "tiempo de sistema" para producción y una implementación de "stub" para pruebas, o puede implementarla usted mismo.

Puede usar la misma idea sin usar Noda Time, por supuesto. Para probar esta pieza de código en particular, es posible que desee pasar la fecha, pero la obtendrá de en algún lugar - e inyectando un reloj significa que puede probar todo el código.

+0

+1. "puede necesitar usar Utc" es un buen punto. Además del valor de caché de "ahora", sería mejor pasarlo como argumento a una función para que pueda probarlo en una unidad (el código de prueba con DateTime.Today/DateTime.Now no es fácil). –

+0

@AlexeiLevenkov: O inyecta un reloj, sí. Agregaré eso. –

+2

El miembro del tipo especificado 'Fecha' no se admite en LINQ to Entities. Solo se admiten inicializadores, miembros de entidades y propiedades de navegación de entidades. – SAR

2

Trate

var q = db.Games.Where(t => t.StartDate.Date >= DateTime.Now.Date).OrderBy(d => d.StartDate); 
+1

Consulte mi respuesta para saber por qué esa no es una buena idea; también, DateTime.Today es un enfoque más simple. –

+0

@JonSkeet: Buen punto. No entendí eso. Ese es exactamente uno de esos errores que nunca sucederían durante el desarrollo (¡porque probablemente estés probando durante el día) y en cambio volverá y te atormentará más tarde! –

59

La propiedad La fecha no es soportado por LINQ a Entidades - obtendrá un error si se intenta utilizar en un campo DateTime en una LINQ a Entidades consulta. Sin embargo, puede recortar fechas usando el método DbFunctions.TruncateTime.

var today = DateTime.Today; 
var q = db.Games.Where(t => DbFunctions.TruncateTime(t.StartDate) >= today); 
+13

Solo una nota, 'EntityFunctions' ahora ha sido reemplazado por' DbFunctions' en versiones posteriores de Entity Framework –

+0

Soy el único que su solución y la solución de Jon me plantean el error "El miembro de tipo especificado 'Fecha' no es compatible con LINQ to Entities "? – ihebiheb

+2

Esto no funciona cuando está respaldado por MySql DB. – sheamus

7

me encontré con que en mi caso esta es la única forma de trabajo: (en mi solicitud Quiero eliminar entradas de registro antiguos)

var filterDate = dtRemoveLogs.SelectedDate.Value.Date; 
var loadOp = context.Load<ApplicationLog>(context.GetApplicationLogsQuery() 
       .Where(l => l.DateTime.Year <= filterDate.Year 
         && l.DateTime.Month <= filterDate.Month 
         && l.DateTime.Day <= filterDate.Day)); 

No entiendo por qué la solución de Jon no es trabajo ....

+0

¿Por qué está comparando la propiedad 'Month' de un' DateTime' con la propiedad 'Year' del otro? – BACON

+0

Editado ... Gracias. – Caesar

1
DateTime dt=DateTime.Now.date; 

var q = db.Games.Where(
    t =>EntityFunction.TruncateTime(t.StartDate.Date >=EntityFunction.TruncateTime(dt)).OrderBy(d => d.StartDate 
); 
+1

¡Utilice el formato de código para proporcionar respuestas legibles! –

18

Prueba este código

var today = DateTime.Today; 
var q = db.Games.Where(t => DbFunctions.TruncateTime(t.StartDate) <= today); 
8

Ocurre que a LINQ no le gustan las propiedades como DateTime.Date. Simplemente no puede convertir a consultas SQL. Así que descubrí una forma de comparar fechas usando la respuesta de Jon, pero sin ese pícaro DateTime.Date. Algo como esto:

var q = db.Games.Where(t => t.StartDate.CompareTo(DateTime.Today) >= 0).OrderBy(d => d.StartDate);

De esta manera, estamos comparando una base de datos completa DateTime, con todo lo que la fecha y hora cosas, como 04/03/2015 11: 49: 45,000 o algo así, con un DateTime que representa el primer milisegundo real de ese día, como 2015-03-04 00: 00: 00.0000.

Cualquier DateTime que comparemos con esa DateTime.Today nos devolverá de manera segura si esa fecha es posterior o la misma. A menos que quieras comparar literalmente el mismo día, en cuyo caso creo que deberías ir por la respuesta de César.

El método DateTime.CompareTo() es simplemente un material de lujo orientado a objetos. Devuelve -1 si el parámetro es anterior al DateTime al que hizo referencia, 0 si es LITERALMENTE IGUAL (con todas esas cosas de tiempo) y 1 si es posterior.

Cuestiones relacionadas