c# exemple - LINQ To Entities ne reconnaît pas la méthode Last. Vraiment?




2 Answers

Cette limitation se résume au fait que finalement il doit traduire cette requête en SQL et SQL a un SELECT TOP (en T-SQL) mais pas un SELECT BOTTOM (pas une telle chose).

Il y a un moyen facile de contourner cela, il suffit d' ordonner de descendre et de faire un First() , ce que vous avez fait.

EDIT: D'autres fournisseurs auront peut-être des implémentations différentes de SELECT TOP 1 , sur Oracle ce serait probablement quelque chose de plus comme WHERE ROWNUM = 1

MODIFIER:

Une autre alternative moins efficace - Je ne recommande pas cela! - est d'appeler .ToList() sur vos données avant .Last() , qui exécutera immédiatement l'expression LINQ To Entities qui a été construite jusqu'à ce point, puis votre .Last () fonctionnera, car à ce moment le .Last() est effectivement exécuté dans le contexte d'une expression LINQ to Objects à la place. (Et comme vous l'avez souligné, cela pourrait ramener des milliers d'enregistrements et gaspiller des charges matérielles d'UC qui ne seront jamais utilisées)

Encore une fois, je ne recommanderais pas de faire cette seconde, mais cela aide à illustrer la différence entre où et quand l'expression LINQ est exécutée.

queries cours

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

Je devais passer à cela pour que ça marche

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() , pour refléter la première requête.

Pourquoi y a-t-il des limites aussi fondamentales dans un système ORM aussi robuste?




Remplacer Last() par un sélecteur Linq OrderByDescending(x => x.ID).Take(1).Single()

Quelque chose comme ça serait efficace si vous préférez le faire dans Linq:

public static IEnumerable<IServerOnlineCharacter> GetUpdated()
{
    var context = DataContext.GetDataContext();
    return context.ServerOnlineCharacters.OrderBy(p => p.ServerStatus.ServerDateTime).GroupBy(p => p.RawName).Select(p => p.OrderByDescending(x => x.Id).Take(1).Single());
}



Related

c# entity-framework orm