J'ai deux valeurs de date, une déjà stockée dans la base de données et l'autre sélectionnée par l'utilisateur à l'aide de DatePicker. Le cas d'utilisation consiste à rechercher une date particulière dans la base de données.
La valeur précédemment entrée dans la base de données a toujours une composante heure de 12:00:00, la date entrée dans le sélecteur ayant une composante heure différente.
Je ne m'intéresse qu'aux composants de la date et je voudrais ignorer le composant de l'heure.
Quels sont les moyens de faire cette comparaison en C #?
Aussi, comment faire cela dans LINQ?
UPDATE: Sur LINQ to Entities, les éléments suivants fonctionnent correctement.
e => DateTime.Compare(e.FirstDate.Value, SecondDate) >= 0
REMARQUE: au moment de la rédaction de cette réponse, la relation EF n'était pas claire (elle a été intégrée à la question après sa rédaction). Pour une approche correcte avec EF, vérifiez réponse Mandeeps .
Vous pouvez utiliser le DateTime.Date
propriété pour effectuer une comparaison par date.
DateTime a = GetFirstDate();
DateTime b = GetSecondDate();
if (a.Date.Equals(b.Date))
{
// the dates are equal
}
Utilisez la classe EntityFunctions
pour rogner la partie temporelle.
using System.Data.Objects;
var bla = (from log in context.Contacts
where EntityFunctions.TruncateTime(log.ModifiedDate) == EntityFunctions.TruncateTime(today.Date)
select log).FirstOrDefault();
[~ # ~] met à jour [~ # ~]
A partir de EF 6.0, les EntityFunctions sont remplacées par DbFunctions .
Je pense que cela pourrait vous aider.
J'ai fait une extension car je dois comparer les dates dans des référentiels remplis de données EF. Ainsi, Date n'était pas une option, car il n'est pas implémenté dans la traduction LinqToEntities.
Voici le code:
/// <summary>
/// Check if two dates are same
/// </summary>
/// <typeparam name="TElement">Type</typeparam>
/// <param name="valueSelector">date field</param>
/// <param name="value">date compared</param>
/// <returns>bool</returns>
public Expression<Func<TElement, bool>> IsSameDate<TElement>(Expression<Func<TElement, DateTime>> 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<Func<TElement, bool>>(body, p);
}
alors vous pouvez l'utiliser de cette façon.
var today = DateTime.Now;
var todayPosts = from t in turnos.Where(IsSameDate<Turno>(t => t.MyDate, today))
select t);
Si vous utilisez la propriété Date
pour les entités de base de données, vous obtiendrez une exception:
"The specified type member 'Date' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported."
Vous pouvez utiliser quelque chose comme ceci:
DateTime date = DateTime.Now.Date;
var result = from client in context.clients
where client.BirthDate >= date
&& client.BirthDate < date.AddDays(1)
select client;
Voici une manière différente de le faire, mais elle n’est utile que si SecondDate est une variable que vous transmettez:
DateTime startDate = SecondDate.Date;
DateTime endDate = startDate.AddDays(1).AddTicks(-1);
...
e => e.FirstDate.Value >= startDate && e.FirstDate.Value <= endDate
Je pense que ça devrait marcher
Pour le faire dans LINQ to Entities, vous devez utiliser méthodes supportées :
var year = someDate.Year;
var month = ...
var q = from r in Context.Records
where Microsoft.VisualBasic.DateAndTime.Year(r.SomeDate) == year
&& // month and day
Moche, mais ça marche, et c'est fait sur le serveur de base de données.
Vous pouvez également utiliser ceci:
DbFunctions.DiffDays(date1, date2) == 0
vous pouvez utiliser la méthode DbFunctions.TruncateTime () pour cela.
e => DbFunctions.TruncateTime(e.FirstDate.Value) == DbFunctions.TruncateTime(SecondDate);
Il suffit de toujours comparer la propriété Date de DateTime au lieu de la date complète.
Lorsque vous effectuez votre requête LINQ, utilisez date.Date dans la requête, c'est-à-dire:
var results = from c in collection
where c.Date == myDateTime.Date
select c;
C'est comme ça que je fais ça.
DateTime date_time_to_compare = DateTime.Now;
//Compare only date parts
context.YourObject.FirstOrDefault(r =>
EntityFunctions.TruncateTime(r.date) == EntityFunctions.TruncateTime(date_to_compare));
// Note pour les utilisateurs/codeurs Linq
Cela devrait vous donner la comparaison exacte pour vérifier si une date se situe dans la plage lorsque vous utilisez une entrée à partir d'un sélecteur de date utilisateur, par exemple:
((DateTime)ri.RequestX.DateSatisfied).Date >= startdate.Date &&
((DateTime)ri.RequestX.DateSatisfied).Date <= enddate.Date
où startdate et enddate sont les valeurs d'un sélecteur de date.
Juste si quelqu'un arrive ici en train de googler ou de bavarder ... Solutions de contournement compilées:
Sans temps que d'essayer comme ça:
TimeSpan ts = new TimeSpan(23, 59, 59);
toDate = toDate.Add(ts);
List<AuditLog> resultLogs =
_dbContext.AuditLogs
.Where(al => al.Log_Date >= fromDate && al.Log_Date <= toDate)
.ToList();
return resultLogs;
Vous pouvez utiliser le lien ci-dessous pour comparer 2 dates sans heure:
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 fonction Compare renvoie 3 valeurs différentes: -1 0 1, ce qui signifie dt1> dt2, dt1 = dt2, dt1
Essayez ceci ... Cela fonctionne bien pour comparer les propriétés de date entre deux types de DateTimes:
PS C'est une solution provisoire et une très mauvaise pratique à ne pas utiliser si vous savez que la base de données peut contenir des milliers d'enregistrements ...
query = query.ToList()
.Where(x => x.FirstDate.Date == SecondDate.Date)
.AsQueryable();