web-dev-qa-db-fra.com

Last et LastOrDefault non pris en charge

J'essaye d'obtenir la première valeur dans la liste et la dernière valeur. L'opérateur de requête First() est pris en charge mais Last() et LastOrDefault() donne une erreur. Suis-je en train d'utiliser l'opérateur Last() de manière incorrecte?

   var purchaseBills = db.PurchaseBills.OrderBy(p => p.BillID);

   if (purchaseBills.Count() >0)
   {
       var firstBill= purchaseBills.First(); //This is supported

       //Attempt 1                    
       var lastBill = purchaseBills.Last(); // Not supported

       //Attempt 2
       var lastBill = purchaseBills.LastOrDefault(); //Not supported

       //Attempt 3
       var lastBill = purchaseBills.Reverse().First(); //Not supported

       textBoxPurchaseBillFrom.Text = firstBill.BillNo.ToString();
       textBoxPurchaseBillTo.Text = lastBill.BillNo.ToString();
   }

Mise à jour: --Erreurs--

Tentative 1: l'opérateur de requête "Dernier" n'est pas pris en charge.

Tentative 2: l'opérateur de requête "LastOrDefault" n'est pas pris en charge.

Tentative 3: L'opérateur de requête "Reverse" n'est pas pris en charge.

39
Marshal
  • Au lieu de le mettre dans une propre liste en appelant ToList() ou ToArray() je préférerais utiliser AsEnumerable().
  • De plus, comme les autres, vous devriez essayer OrderByDescending()
  • Au lieu de Count() j'utiliserais Any().
47
Oliver

soit vous passez votre OrderBy à

.OrderByDescending(p => p.BillID)

(et utilisez d'abord) ou vous faites quelque chose comme

purchaseBills.ToArray().Last()

si ce n'est pas trop cher.

22
Carsten

Last n'est pas pris en charge par la base de données principale. Vous devriez essayer d'autres techniques:

  1. Exécutez votre requête à l'aide de OrderByDescending pour que l'élément demandé soit prioritaire.

  2. Codez votre requête LINQ comme d'habitude, mais appliquez Linq2Sql pour la restituer à une collection CLR et vous aurez alors un accès gratuit à tout localement, y compris Last. Exemple:

    var bills = purchaseBills.ToList();
    var last = bills.Last();
    
18
user326563

Le problème est qu'il n'y a pas de traduction facile en SQL pour Last ou Reverse, donc convertissez-le en quelque chose en mémoire (ToList, ToArray) s'il y a ne va pas être trop d'enregistrements, ou vous pouvez exécuter la requête une deuxième fois, avec OrderByDescending au lieu de OrderBy et utiliser First.

10
George Duckett

J'essaie de ne pas utiliser LastOrDefault() parce que parfois cela ne fonctionne pas ou ne prend pas en charge. Je trie id par desc, puis récupère les premiers enregistrements.

.OrderByDescending(o=>o.id)
.FirstOrDefault(s => s.Name == Name)
6
Lap Huynh

Cela a quelque chose à voir avec le fait que l'opérateur Last essaie d'être envoyé au serveur SQL qui n'a pas de commande correspondante. Une fois que la solution est de mettre une ToArray() ou Tolist() à la fin de votre appel db, ce qui fait de cette ligne un appel explicite pour obtenir les données (au lieu de charger paresseusement les uns sur les autres) lignes).

2
Erik Philips

Encore une autre façon d'obtenir le dernier élément sans ordre croissant et de charger toutes les entités:

var lastBill = purchaseBills
    .Where(f => f.BillID == purchaseBills.Max(f2 => f2.BillID))
    .FirstOrDefault();
1
Stas Boyarincev