LINQ to entities ne reconnaît pas la méthode la Dernière. Vraiment?
Dans cette requête:
public static IEnumerable<IServerOnlineCharacter> GetUpdated()
{
var context = DataContext.GetDataContext();
return context.ServerOnlineCharacters
.OrderBy(p => p.ServerStatus.ServerDateTime)
.GroupBy(p => p.RawName)
.Select(p => p.Last());
}
J'ai dû changer de il pour il pour travailler
public static IEnumerable<IServerOnlineCharacter> GetUpdated()
{
var context = DataContext.GetDataContext();
return context.ServerOnlineCharacters
.OrderByDescending(p => p.ServerStatus.ServerDateTime)
.GroupBy(p => p.RawName)
.Select(p => p.FirstOrDefault());
}
Je ne pouvais même pas utiliser p.First()
, au miroir de la première requête.
Pourquoi y at-il des limitations de base dans ce qui est autrement une telle robuste ORM système?
- stocker vos IEnumrable objet dans une nouvelle variable, la variable de retour.last(). il va travailler.
Vous devez vous connecter pour publier un commentaire.
Cette limitation vient du fait que, finalement, il doit traduire cette requête à SQL et SQL dispose d'un
SELECT TOP
(T-SQL), mais pas unSELECT BOTTOM
(pas une telle chose).Il est un moyen facile autour d'elle si, juste ordre décroissant et puis faire un
First()
, qui est ce que vous avez fait.EDIT:
D'autres fournisseurs peut avoir différentes implémentations de
SELECT TOP 1
, sur l'Oracle, il serait probablement quelque chose de plus commeWHERE ROWNUM = 1
EDIT:
Un autre moins efficace alternative - je NE recommande PAS cet! - est d'appeler
.ToList()
sur vos données avant de.Last()
, qui sera immédiatement exécuter le LINQ to entities Expression qui a été construit jusqu'à ce point, et alors votre .Last() va fonctionner, parce que à ce moment la.Last()
est bien exécuté dans le contexte d'une LINQ to Objects Expression à la place. (Et comme vous l'avez souligné, il pourrait ramener des milliers de dossiers et de déchets de charge de CPU matérialisation des objets qui ne sera jamais utilisé)Encore une fois, je ne recommande pas de faire cette seconde, mais il ne vous aider à illustrer la différence entre où et quand l'expression LINQ est exécutée.
Last()
est surEnumerable
.ToList
n'est pas mauvais.Au lieu de
Last()
, Essayez ceci:Remplacer
Last()
par une Linq sélecteur deOrderByDescending(x => x.ID).Take(1).Single()
Quelque chose comme ça serait œuvres si vous prefert le faire dans Linq :
Encore une autre façon d'obtenir le dernier élément sans OrderByDescending et de charger toutes les entités:
C'est parce que LINQ to entities (et les bases de données en général) ne prend pas en charge toutes les méthodes LINQ (voir ici pour les détails: http://msdn.microsoft.com/en-us/library/bb738550.aspx)
Ce dont vous avez besoin ici est de l'ordre de vos données d'une façon telle que le "dernier" est "d'abord", et puis vous pouvez utiliser FirstOrDefault. Notez que databasese n'ont généralement pas de notions telles que le "premier" et "dernier", ce n'est pas comme le plus récemment enregistrement inséré sera le "dernier" dans le tableau.
Cette méthode peut résoudre votre problème
L'ajout d'une fonction unique
AsEnumerable()
avant de Sélectionner la fonction a fonctionné pour moi.Exemple:
Réf.:
https://www.codeproject.com/Questions/1005274/LINQ-to-Entities-does-not-recognize-the-method-Sys