2010-07-13 21 views
1

IS est un problème d'exécution différée. Cependant, mon problème provient du fait que je ne peux pas déterminer POURQUOI cette exécution est parfois retardée, et pas d'autres fois.LINQ Exécution étrange - Inconsistantly Consistant?

code:

IList<LineItem> freeFlatItems = new List<LineItem>(); 

if(QualifyFreeFlatShipping) 
    freeFlatItems = lineItems.Where(l => l.FlatShippingRate != null).ToList(); 

decimal? freeFlatShippingTotal = freeFlatItems.Sum(l => l.FlatShippingRate); 

var globalShippingPromos = _promoService.GetGlobalShippingPromos(); 

Problème:

Ce code est en production, et fonctionne comme prévu. J'ai récemment changé ailleurs et j'ai constaté que ce test ne fonctionnait pas dans nos tests unitaires. Lorsque je passe à travers cette fonction, ce qui suit se produit:

  1. Avant d'atteindre ce code, j'ai vérifié les données d'entrée. Tous les éléments de lineItems. Chaque article a en tant que valeur pour .FlatShippingRate
  2. QualifyFreeFlatShipping est true
  3. exécution de code atteint la statment LINQ à la ligne 4 (freeFlatItems = etc...)
  4. Valeur de freeFlatItems reste inchangée tant que l'exécution se poursuit à la ligne 6 (decimal? freeFlatShippingTotal = etc...)
  5. .Sum est exécuté sur une liste vide.
  6. En atteignant la ligne 8 (var globalShippingPromos = etc...) la valeur de freeFlatItems enfin met à jour à ce que devrait être être. Cependant ... la somme a été exécutée sur la valeur précédente, et mon total d'expédition est incorrect.

La question (s):

  1. Pourquoi est-ce toujours en retard? Je pensais .ToList() forcé l'exécution de la linq pour générer le IList<T>
  2. Pourquoi cela se comporte différemment d'une manière consistante? (Mon test se comporte toujours de cette façon, la production fonctionne bien, ce code dans LinqPad fonctionne bien). Et avant que vous le suggériez, j'ai validé mon test est construit correctement. À la fois dans le code de test et dans la première étape ci-dessus en validant les données d'entrée dans le débogueur.

Répondre

0

Je ne pense pas que ce soit un problème avec l'exécution retardée. Mais je peux suggérer une façon plus simple d'écrire le code.

decimal freeFlatShippingTotal = 0.0m; 
if(QualifyFreeFlatShipping) 
    freeFlatShippingTotal = lineItems.Sum(l => l.FlatShippingRate ?? 0.0m); 
+0

L'autre code plus bas a besoin de la liste des éléments freeFlat. – Aren

2

1.

Il n'y a pas d'exécution différée ici. Le "Où" est forcé par ToList(), et le "Sum" est évalué immédiatement et stocké dans la décimale. L'erreur doit être quelque part ailleurs

2.

Lorsque vous évaluez la somme une seconde fois, après la ligne 8, permet de dire avec:

decimal? freeFlatShippingTotal2 = freeFlatItems.Sum(l => l.FlatShippingRate); 

ne vous obtenez alors la valeur correcte? Donc, freeFlatShippingTotal2! = FreeFlatShippingTotal?

+0

Oh wow, merci d'avoir pris le temps de répondre. Cette question a cependant 2 mois, je ne me souviens malheureusement pas beaucoup de ce qui s'est passé. Je pense que j'ai ré-factorisé certaines choses et que je l'ai abordé complètement différemment pour contourner cela. Je vais vous donner +1 pour prendre le temps si longtemps après :) – Aren

+0

Je ne sais pas comment j'ai trouvé cette question, mais je ne savais pas que c'était si vieux ;-) Merci! – Chris