¿Cómo comparar solo los componentes de fecha de DateTime en EF?

Estoy teniendo dos valores de fecha, uno ya almacenado en la base de datos y el otro seleccionado por el usuario usando DatePicker. El caso de uso es buscar una fecha particular de la base de datos.

El valor previamente ingresado en la base de datos siempre tiene un componente de tiempo de 12:00:00, mientras que la fecha ingresada desde el selector tiene un componente de tiempo diferente.

Estoy interesado solamente en los componentes de la fecha y me gustaría ignorar el componente de tiempo.

¿Cuáles son las formas de hacer esta comparación en C #?

Además, ¿cómo hacer esto en LINQ?

ACTUALIZACIÓN: en LINQ to Entities, lo siguiente funciona bien.

e => DateTime.Compare(e.FirstDate.Value, SecondDate) >= 0 

NOTA: en el momento de escribir esta respuesta, la relación EF no estaba clara (eso fue editado en la pregunta después de que esto fue escrito). Para una aproximación correcta con EF, verifique la respuesta de Mandeeps .


Puede usar la propiedad DateTime.Date para realizar una comparación de solo fecha.

 DateTime a = GetFirstDate(); DateTime b = GetSecondDate(); if (a.Date.Equals(b.Date)) { // the dates are equal } 

Use la clase EntityFunctions para recortar la porción de tiempo.

 using System.Data.Objects; var bla = (from log in context.Contacts where EntityFunctions.TruncateTime(log.ModifiedDate) == EntityFunctions.TruncateTime(today.Date) select log).FirstOrDefault(); 

Fuente: http://social.msdn.microsoft.com/Forums/en-US/csharpgeneral/thread/84d4e18b-7545-419b-9826-53ff1a0e2a62/

ACTUALIZAR

A partir de EF 6.0 y posteriores EntityFunctions se reemplaza por DbFunctions .

Creo que esto podría ayudarte.

Hice una extensión ya que tengo que comparar fechas en repositorys llenos de datos de EF, por lo que .Fecha no fue una opción ya que no está implementada en la traducción de LinqToEntities.

Aquí está el código:

  ///  /// Check if two dates are same ///  /// Type /// date field /// date compared /// bool public Expression> IsSameDate(Expression> valueSelector, DateTime value) { ParameterExpression p = valueSelector.Parameters.Single(); var antes = Expression.GreaterThanOrEqual(valueSelector.Body, Expression.Constant(value.Date, typeof(DateTime))); var despues = Expression.LessThan(valueSelector.Body, Expression.Constant(value.AddDays(1).Date, typeof(DateTime))); Expression body = Expression.And(antes, despues); return Expression.Lambda>(body, p); } 

entonces puedes usarlo de esta manera.

  var today = DateTime.Now; var todayPosts = from t in turnos.Where(IsSameDate(t => t.MyDate, today)) select t); 

Si usa la propiedad Date para las entidades DB, obtendrá una excepción:

 "The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported." 

Puedes usar algo como esto:

  DateTime date = DateTime.Now.Date; var result = from client in context.clients where client.BirthDate >= date && client.BirthDate < date.AddDays(1) select client; 

Para hacerlo en LINQ to Entities, debes usar los métodos compatibles :

 var year = someDate.Year; var month = ... var q = from r in Context.Records where Microsoft.VisualBasic.DateAndTime.Year(r.SomeDate) == year && // month and day 

Feo, pero funciona, y está hecho en el servidor de bases de datos.

Aquí hay una manera diferente de hacerlo, pero solo es útil si SecondDate es una variable que está pasando:

 DateTime startDate = SecondDate.Date; DateTime endDate = startDate.AddDays(1).AddTicks(-1); ... e => e.FirstDate.Value >= startDate && e.FirstDate.Value <= endDate 

Creo que debería funcionar

También puedes usar esto:

DbFunctions.DiffDays(date1, date2) == 0

Simplemente compare siempre la propiedad Date de DateTime, en lugar de la fecha completa.

Cuando realiza su consulta LINQ, use date.Date en la consulta, es decir:

 var results = from c in collection where c.Date == myDateTime.Date select c; 

Solo si alguien llega aquí haciendo búsquedas en Google o atracones … comstackción de soluciones:

http://blog.integratedsolution.eu/post/2011/02/06/The-specified-type-member-Date-is-not-supported-in-LINQ-to-Entities.aspx

Así es como hago esto.

 DateTime date_time_to_compare = DateTime.Now; //Compare only date parts context.YourObject.FirstOrDefault(r => EntityFunctions.TruncateTime(r.date) == EntityFunctions.TruncateTime(date_to_compare)); 

// Nota para los usuarios / codificadores de Linq

Esto debería darle la comparación exacta para verificar si una fecha está dentro del rango cuando se trabaja con la información de un usuario – selector de fecha, por ejemplo:

 ((DateTime)ri.RequestX.DateSatisfied).Date >= startdate.Date && ((DateTime)ri.RequestX.DateSatisfied).Date <= enddate.Date 

donde startdate y enddate son valores de un selector de fecha.

puede usar el método DbFunctions.TruncateTime () para esto.

 e => DbFunctions.TruncateTime(e.FirstDate.Value) == DbFunctions.TruncateTime(SecondDate); 

Puede utilizar el siguiente enlace para comparar 2 fechas sin tiempo:

 private bool DateGreaterOrEqual(DateTime dt1, DateTime dt2) { return DateTime.Compare(dt1.Date, dt2.Date) >= 0; } private bool DateLessOrEqual(DateTime dt1, DateTime dt2) { return DateTime.Compare(dt1.Date, dt2.Date) <= 0; } 

la función Comparar devuelve 3 valores diferentes: -1 0 1 lo que significa dt1> dt2, dt1 = dt2, dt1

Sin tiempo que probar así:

 TimeSpan ts = new TimeSpan(23, 59, 59); toDate = toDate.Add(ts); List resultLogs = _dbContext.AuditLogs .Where(al => al.Log_Date >= fromDate && al.Log_Date <= toDate) .ToList(); return resultLogs; 

Intenta esto … Funciona bien para comparar las propiedades de Fecha entre dos tipos de DateTimes:

PD. Es una solución provisional y una práctica realmente mala, nunca debe usarse cuando sabes que la base de datos puede traer miles de registros …

 query = query.ToList() .Where(x => x.FirstDate.Date == SecondDate.Date) .AsQueryable();