2009-02-20 13 views
55

Sto cercando di determinare il numero di giorni tra 2 date utilizzando LINQ con Entity Framework. Mi sta dicendo che non riconosce Sottrazione sulla classe System.TimeSpanLINQ alle entità per la sottrazione di 2 date

Ecco la parte della query LINQ in cui mi trovo.

where ((DateTime.Now.Subtract(vid.CreatedDate).TotalDays < maxAgeInDays)) 

Qui è l'errore che ricevo nel debugger VS.NET

{metodo "LINQ to Entities non riconosce il metodo 'System.TimeSpan Sottrai (System.DateTime)', e questo metodo non può essere tradotto in un'espressione di negozio. "}

Sto facendo qualcosa di sbagliato o c'è un modo migliore per ottenere il numero di giorni tra 2 DateTimes nel quadro di entità?

grazie Michael

+0

Ho anche cercato di evitare periodo modificando la formula un po 'al seguente - che ancora non funziona dove (vid.CreatedDate.AddDays (maxAgeInDays)> = DateTime.Now) –

risposta

41

Ecco come ho preso a lavorare

ho definito una variabile datetime che rappresenta la data più antica

DateTime oldestDate = DateTime.Now.Subtract(new TimeSpan(maxAgeInDays, 0, 0, 0, 0)); 
... 

poi ho modificato la parte in cui la query LINQ

where (vid.CreatedDate >= oldestDate) 

ha funzionato come un incantesimo - grazie Micah per avermi fatto riflettere sull'albero delle espressioni

+2

Dovresti aver contrassegnato @Micah come risposta e aggiungere un commento alla sua risposta o aggiornare la tua domanda con la risposta finale. – ongle

+0

Intelligente, intelligente intelligente. Semplice e diretto. Mi sto ancora chiedendo perché non è venuto da me in primo luogo. Grazie per aver condiviso –

11

si esegue in questo tipo di isses perché il predicato deve essere tradotto in un albero di espressione. E il processo di traduzione non riconosce il metodo DateTime.Now.Subtract.

+0

Esiste un modo per fare ciò che Sto cercando di fare in modo che possa essere tradotto in un albero di espressione? –

1

Il fatto è che, in base alla progettazione, LINQ to Entities deve tradurre l'intera query in istruzioni SQL. È lì che non può riconoscere il metodo Sottrai. Si verificherà ogni volta che si tenta di utilizzare un metodo C#/VB all'interno di una query. In questi casi devi capire un modo per far emergere quella parte dalla query. Questo post spiega un po 'di più: http://mosesofegypt.net/post/LINQ-to-Entities-what-is-not-supported.aspx

+0

Questa risposta è corretta, ma sicuramente non è la risposta che volevo. LINQ to SQL ha supportato la chiamata di metodi esterni quanto desiderato, quindi questo trade-off è sfortunato. –

+2

il link è morto. – Bijan

90

La risposta accettata è meglio in questo caso, ma per riferimento è possibile utilizzare la classe EntityFunctions per eseguire le operazioni in date, tra le altre cose.

where (vid.CreatedDate >= EntityFunctions.AddDays(DateTime.Now, -maxAgeInDay)) 
+0

Grazie, questo è esattamente quello che stavo cercando. – wdanda

+3

Si noti che questo è supportato solo in Entity Framework v4. Questo non funzionerà con Entity Framework v1. –

+0

Grazie per aver condiviso la classe EntityFunctions. Molto utile – StackThis

18

è anche possibile utilizzare System.Data.Objects.EntityFucntions:

currentDate = DateTime.Now; 

... 
where EntityFunctions.DiffDays(currentDate, vid.CreatedDate) < maxAgeIdDays 

Tutte le funzioni di EntityFunctions sono solo per LINQ-to-entità e sono mappati funzioni SQL.

+0

Funzionano anche per Linq alle entità. –

+0

@Morten: era di tipo, funzionano solo con le entità Linq. –

+0

Molte funzioni specifiche di SQL Server sono disponibili tramite la classe 'System.Data.Objects.SqlClient.SqlFunctions'. Ovviamente, l'archivio dati deve essere un server SQL perché funzioni. Maggiori informazioni: http://msdn.microsoft.com/en-us/library/system.data.objects.sqlclient.sqlfunctions.aspx – bernhof

0

È possibile definire nuova proprietà nel modello:

public DateTime StartDate{ get; set; } 
    public DateTime EndDate{ get; set; } 
    public TimeSpan CalculateTime{ 
     get 
     { 
      return EndDate.Subtract(StartDate); 
     } 
    } 

Ora, si può usare qualcosa di simile:

var query = from temp in db.Table 
select new MyModel { 
    Id = temp.Id, 
    Variable1 = temp.Variable1, 
    ... 
    EndDate = temp.EndDate, 
    StartDate = temp.StartDate 
} 

Quando si dispone di sguardo risultato, è possibile utilizzare il ritorno come ad esempio:

return query 

Ora, nella query, abbiamo CalculateTime (sottrarre tra EndDate e Startdate).

Problemi correlati