TimeSpan time24 = new TimeSpan(24, 0, 0);
TimeSpan time18 = new TimeSpan(18, 0, 0);
// first get today's sleeping hours
List<Model.Sleep> sleeps = context.Sleeps.Where(
o => (clientDateTime - o.ClientDateTimeStamp < time24) &&
o.ClientDateTimeStamp.TimeOfDay > time18 &&
clientDateTime.TimeOfDay < time18 &&
o.UserID == userid).ToList();
Cette expression Linq lève cette exception:
DbArithmeticExpression arguments must have a numeric common type.
Veuillez aider!
L'arithmétique avec DateTime
n'est pas prise en charge dans Entity Framework 6 et versions antérieures. Vous devez utiliser DbFunctions *. Donc, pour la première partie de votre déclaration, quelque chose comme:
var sleeps = context.Sleeps(o =>
DbFunctions.DiffHours(o.ClientDateTimeStamp, clientDateTime) < 24);
Notez que la méthode DiffHours
accepte Nullable<DateTime>
.
Le noyau Entity Framwork (lorsqu'il est utilisé avec Sql Server, peut-être d'autres fournisseurs de base de données) prend en charge les fonctions DateTime AddXxx
(comme AddHours
). Ils sont traduits en DATEADD
en SQL.
* EntityFunctions
avant la version 6 d'Entity Framework.
Je sais que c'est une vieille question mais dans votre cas spécifique au lieu d'utiliser DBFunctions
comme suggéré par @GertArnold, ne pourriez-vous pas simplement inverser l'opération pour sortir l'arithmétique en question du Lambda?
Après tout clientDateTime
et time24
sont des valeurs fixes, leur différence n'a donc pas besoin d'être recalculée à chaque itération.
Comme:
TimeSpan time24 = new TimeSpan(24, 0, 0);
TimeSpan time18 = new TimeSpan(18, 0, 0);
var clientdtminus24 = clientDateTime - time24;
// first get today's sleeping hours
List<Model.Sleep> sleeps = context.Sleeps.Where(
o => (clientdtminus24 < o.ClientDateTimeStamp) &&
o.ClientDateTimeStamp.TimeOfDay > time18 &&
clientDateTime.TimeOfDay < time18 &&
o.UserID == userid).ToList();
Ce refactor est généralement possible si vous essayez de comparer le datetime stocké décalé par un horodatage fixe avec un autre datetime.
Dans l'autre sens, si les performances ne sont pas le véritable objectif, vous pouvez essayer d'utiliser AsEnumerable()
. Donc, ce serait comme
List<Model.Sleep> sleeps = context.Sleeps.AsEnumerable().Where(....
L'ajout de AsEnumerable () convertira la requête SQL en entité et permet d'exécuter des fonctions .Net sur ces derniers. Pour plus d'informations, vérifiez ici à propos d'AsEnumerable