2011-08-31 2 views
32

J'essaie 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. Est-ce que j'utilise l'opérateur Last() de manière incorrecte?Last et LastOrDefault non pris en charge

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: --Errors--

Tentative 1: L'opérateur de requête 'Last' 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.

+0

Quelle est l'erreur? Quel fournisseur de requêtes utilisez-vous? –

+0

La duplication possible de [LINQ To Entities ne reconnaît pas la méthode Last. Vraiment?] (Http://stackoverflow.com/questions/7293639/linq-to-entities-does-not-recognize-the-method-last-really). Cette question a été posée un mois avant l'autre question, mais cette question a de meilleures réponses. –

Répondre

35
  • au lieu de le mettre dans une propre liste en appelant ToList() ou ToArray() je préférerais utiliser AsEnumerable().
  • En outre, comme les autres vous devriez essayer OrderByDescending()
  • Au lieu de Count() je voudrais utiliser Any().
+2

+1 pour une suggestion Any(). Merci :) – Marshal

+1

J'ai trouvé la commande en descendant, puis en utilisant FirstOrDefault() fonctionnera. –

16

soit vous passez votre OrderBy à

.OrderByDescending(p => p.BillID) 

(et utiliser en premier) ou vous faire quelque chose comme

purchaseBills.ToArray().Last() 

si ce n'est pas cher.

10

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

2

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 un ToArray() ou Tolist() à la fin de votre appel db qui fait de cette ligne un appel explicite pour obtenir les données (au lieu de laisser le chargement sur chacune des autres lignes).

12

Last n'est pas pris en charge par le DB principal. Vous devriez essayer d'autres techniques:

  1. Exécutez votre requête à l'aide OrderByDescending afin que votre article demandé vient en premier.

  2. Codez votre requête LINQ comme d'habitude, mais appliquez Linq2Sql pour la rendre dans une collection CLR, puis vous aurez accès à tout ce qui est disponible localement, y compris Last. Exemple:

    var bills = purchaseBills.ToList(); 
    var last = bills.Last(); 
    
5

J'essaye de ne pas utiliser LastOrDefault() parce que parfois il ne fonctionne pas ou ne supporte pas. Je trier id par desc, puis récupérer les premiers enregistrements.

.OrderByDescending(o=>o.id) 
.FirstOrDefault(s => s.Name == Name) 
+0

Même problème, j'ai changé linq pour utiliser orderby en descendant, puis utilisé FirstOrDefault() au lieu de LastorDefault. –

1

Une autre façon encore obtenir le dernier élément sans OrderByDescending et charger toutes les entités:

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