2009-02-20 5 views
55

J'essaie de déterminer le nombre de jours entre 2 dates en utilisant LINQ avec Entity Framework. Il me dit qu'il ne reconnaît pas Subtract sur la classe System.TimeSpanLINQ to Entities pour soustraire 2 dates

Voici ma partie où de la requête LINQ.

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

Voici l'erreur que je reçois dans le débogueur VS.NET

{ "LINQ to Entities ne reconnaît pas la méthode 'System.TimeSpan Soustraire (System.DateTime)' méthode, et ce la méthode ne peut pas être traduite en une expression de magasin. "}

Est-ce que je fais quelque chose de mal ou existe-t-il un meilleur moyen d'obtenir le nombre de jours entre 2 DateTimes dans le framework d'entité?

grâce Michael

+0

J'ai essayé aussi d'éviter timespan en changeant la formule un peu à ce qui suit - qui ne fonctionne toujours pas où (vid.CreatedDate.AddDays (maxAgeInDays)> = DateTime.Now) –

Répondre

41

Voici comment je l'ai eu à travailler

je définissais une variable datetime qui représente la date la plus ancienne

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

alors j'ai modifié le point où la partie de la requête LINQ

where (vid.CreatedDate >= oldestDate) 

a travaillé comme un charme - merci Micah de m'avoir fait penser à l'arbre d'expression

+2

Vous devriez avoir marqué @Micah comme réponse et soit ajouter un commentaire à sa réponse ou mettre à jour votre question avec la réponse finale. – ongle

+0

Intelligent, intelligent intelligent. Simple et direct. Je me demande toujours pourquoi cela ne m'est pas venu en premier lieu. Merci pour le partage –

11

vous rencontrez ce genre de isses parce que le prédicat doit être traduit à un arbre d'expression. Et le processus de traduction ne reconnaît pas la méthode DateTime.Now.Subtract.

+0

est de toute façon de faire ce que J'essaie de le faire pour que je puisse être traduit dans un arbre d'expression? –

1

Le fait est que, par conception, LINQ to Entities doit traduire toute la requête en instructions SQL. C'est là qu'il ne peut pas reconnaître la méthode de soustraction. Il se produira chaque fois que vous essayez d'utiliser une méthode C#/VB dans une requête. Dans ces cas, vous devez trouver un moyen de faire ressortir cette partie de la requête. Ce message explique un peu plus: http://mosesofegypt.net/post/LINQ-to-Entities-what-is-not-supported.aspx

+0

Cette réponse est correcte, mais ce n'est certainement pas la réponse que je voulais. LINQ to SQL a pris en charge l'appel de méthodes extérieures autant que vous le souhaitiez, ce compromis est donc regrettable. –

+2

le lien est mort. – Bijan

90

La réponse acceptée est mieux dans ce cas, mais pour référence, vous pouvez utiliser la classe EntityFunctions pour effectuer des opérations sur les dates, entre autres.

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

Merci, c'est exactement ce que je cherchais. – wdanda

+3

Notez que ceci n'est pris en charge que dans Entity Framework v4. Cela ne fonctionnera pas pour Entity Framework v1. –

+0

Merci d'avoir partagé la classe EntityFunctions. Très utile – StackThis

18

Vous pouvez également utiliser System.Data.Objects.EntityFucntions:

currentDate = DateTime.Now; 

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

Toutes les fonctions de EntityFunctions ne sont que pour Linq à des entités et sont mis en correspondance avec des fonctions SQL.

+0

Ils fonctionnent également pour Linq to Entities. –

+0

@Morten: C'était un type, ils ne fonctionnent qu'avec Linq-to-entities. –

+0

De nombreuses fonctions spécifiques à SQL Server sont disponibles via la classe 'System.Data.Objects.SqlClient.SqlFunctions'. Bien sûr, le magasin de données doit être un serveur SQL pour que cela fonctionne. Plus d'informations: http://msdn.microsoft.com/en-us/library/system.data.objects.sqlclient.sqlfunctions.aspx – bernhof

0

Vous pouvez définir de nouveaux biens dans votre modèle:

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

Maintenant, vous pouvez utiliser quelque chose comme ça:

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

Lorsque vous avez regarder résultat, vous pouvez utiliser retour tels que:

return query 

Maintenant, dans la requête, nous avons CalculateTime (soustraire entre EndDate et Startdate).

Questions connexes