2010-11-10 19 views
85

Nella mia applicazione sto utilizzando Entity Framework.Linq to EntityFramework DateTime

mia tavola

-Article 
-period 
-startDate 

Ho bisogno record che corrispondono =>DateTime.Now > startDate and (startDate + period) > DateTime.Now

ho provato questo codice, ma la sua ora lavorando

Context.Article 
    .Where(p => p.StartDate < DateTime.Now) 
    .Where(p => p.StartDate.AddDays(p.Period) > DateTime.Now) 

Quando eseguo il mio codice la seguente eccezione si verificano

LINQ to Entities does not recognize the method 'System.DateTime AddDays(Double)' method, and this method cannot be translated into a store expression.

+0

Che tipo è 'punto'? 'AddDays' è la funzione sbagliata se è un' double'. –

+0

il tipo di periodi è int – Yucel

risposta

160

Quando si utilizza LINQ su Entity Framework, i predicati all'interno della clausola Where vengono tradotti in SQL. Stai ricevendo quell'errore perché non c'è traduzione in SQL per DateTime.Add() che ha senso.

un work-around rapida sarebbe quella di leggere i risultati del primo Dove dichiarazione in memoria e quindi utilizzare LINQ to Objects per completare il filtraggio:

Context.Article.Where(p => p.StartDate < DateTime.Now) 
       .ToList() 
       .Where(p => p.StartDate.AddDays(p.Period) > DateTime.Now); 

Si potrebbe anche provare il metodo EntityFunctions.AddDays se siete usando .NET 4.0:

Context.Article.Where(p => p.StartDate < DateTime.Now) 
       .Where(p => EntityFunctions.AddDays(p.StartDate, p.Period) 
        > DateTime.Now); 

Nota: In EF 6 è ora System.Data.Entity.DbFunctions.AddDays.

+32

Questa è una soluzione pericolosa, cosa succede se ToList() restituisce un'enorme quantità di dati? –

+0

@Stefan P. - Quindi la prima affermazione leggerebbe un'enorme quantità di dati in memoria. Il secondo metodo dovrebbe andare bene, ma è disponibile solo con .NET 4.0. –

+6

Grazie per il suggerimento EntityFunctions.AddDays Sto usando EF .net 4.0 ma non sapevo su EntityFunctions, cercherò in esso. –

3

Come su sottraendo 2 giorni da DateTime.Now:

Context.Article 
.Where(p => p.StartDate < DateTime.Now) 
.Where(p => p.StartDate > DateTime.Now.Subtract(new TimeSpan(2, 0, 0, 0))) 

Ad essere onesti, non sicuro di quello che si sta cercando di raggiungere, ma questo può funzionare

+0

Gli articoli inizieranno a essere mostrati su StartDate e terminano dopo x (periodo) giorni. Questo è quello che sto cercando di fare. La seconda soluzione di Justin Niessner ha funzionato molto bene per quello che voglio vedere – Yucel

+1

Ho ottenuto lo stesso errore usando Subtract! –

71

Credo che questo è ciò che lo scorso risposta stava cercando di suggerire, ma piuttosto che cercare di aggiungere giorni di tempo per p.startdat (qualcosa che non può essere convertito in una dichiarazione di sql) perché non fare qualcosa che può essere equiparato a SQL:

var baselineDate = DateTime.Now.AddHours(-24); 

something.Where(p => p.startdate >= baselineDate) 
+7

Questa è una risposta molto migliore rispetto alla risposta accettata con più voti. È più semplice, più sicuro e più efficiente. –

+1

@Adrian Carr: può essere migliore per questo caso d'uso ma non per la soluzione 'EntityFunctions'. Qui, il secondo operando non viene recuperato da un'altra entità nella query e può essere calcolato prima dell'interrogazione. Se entrambi gli operandi dovessero essere trovati in db, la soluzione 'EntityFunctions' sarebbe ancora adatta mentre la soluzione di questa risposta non funzionerebbe più. –

1

Se è necessario che l'espressione venga tradotta in SQL, è possibile provare a utilizzare

System.Data.Entity.Core.Objects.AddDays metodo.

In realtà è contrassegnato come obsoleto ma funziona. Dovrebbe essere sostituito da System.Data.Entity.DbFunctions.AddDays ma non riesco a trovarlo ...

+0

Questo aggiunge niente di più della risposta accettata da 4 anni prima! –

+0

@AndrewHarris anche la mia risposta è 4 anni fa risposta. Nella prima versione della risposta c'erano una ToList (=> materializzazione dei dati) prima di Where (vedere il primo commento della risposta). – bubi