Gli argomenti DbArithmeticExpression devono avere un tipo comune numerico


120
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(); 

Questa espressione di Linq genera questa eccezione:

DbArithmeticExpression arguments must have a numeric common type.

Per favore aiuto!


Quali sono i risultati clientDateTime - o.ClientDateTimeStamp?
shahkalpesh

noramlly che dovrebbe essere un oggetto del TimeSpan, in EF viene generata un'eccezione.
Nawaz Dhandala,

Risposte:


247

L'aritmetica con DateTimenon è supportata in Entity Framework 6 e versioni precedenti. Devi usare DbFunctions *. Quindi, per la prima parte della tua dichiarazione, qualcosa del tipo:

var sleeps = context.Sleeps(o =>
    DbFunctions.DiffHours(o.ClientDateTimeStamp, clientDateTime) < 24);

Nota che il DiffHoursmetodo accetta Nullable<DateTime>.

Entity Framwork core (se utilizzato con Sql Server, forse altri provider di database) supporta le AddXxxfunzioni DateTime (come AddHours). Sono tradotti in DATEADDSQL.

* EntityFunctionsprima di Entity Framework versione 6.


2

So che questa è una vecchia domanda ma nel tuo caso specifico invece di usare DBFunctionscome suggerito da @GertArnold, non potresti semplicemente invertire l'operazione spostando l'aritmetica in questione dal Lambda?

Dopotutto clientDateTimee time24sono valori fissi, quindi la loro differenza non deve essere ricalcolata in ogni iterazione.

Piace:

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();

Questo refactor è generalmente possibile se si sta tentando di confrontare il datetime archiviato spostato da un timestamp fisso con un altro datetime.


Ho avuto questa situazione esatta e questo ha aiutato. Tuttavia, lo scopo di questa soluzione è molto limitato a un tipo specifico di problema.
Zimano

@Zimano Risolve il problema degli OP senza richiedergli di cambiare tecnologia o ricorrere a hack. Se può essere modificato in questo modo, fallo, in caso contrario fallo come nella risposta accettata.
Presto morto il

1

Nell'altro modo, se le prestazioni non sono il vero obiettivo, puoi provare a utilizzare AsEnumerable(). Quindi, sarebbe come

List<Model.Sleep> sleeps = context.Sleeps.AsEnumerable().Where(....

L'aggiunta di AsEnumerable () convertirà la query SQL in entità e consentirà di eseguire le funzioni .Net su di esse. Per maggiori informazioni, controlla qui su AsEnumerable

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.