2010-03-16 16 views
2

J'ai une requête Linq assez simple (code simplifié):Utiliser l'état de session dans les requêtes PLINQ

dim x = From Product In lstProductList.AsParallel 
     Order By Product.Price.GrossPrice Descending Select Product 

Le produit est une classe. Product.Price est une classe enfant et GrossPrice est l'une de ses propriétés. Afin de calculer le prix, j'ai besoin d'utiliser Session ("exchange_rate").

Donc, pour chaque élément dans lstProductList il y a une fonction qui effectue les opérations suivantes:

NetPrice=NetPrice * Session("exchange_rate") 

(puis retourne GrossPrice NetPrice + VatAmount)

Peu importe ce que j'ai essayé, je ne peux pas accéder à l'état de session .

J'ai essayé HttpContext.Current - mais cela retourne Nothing. J'ai essayé Implements IRequiresSessionState sur la classe (ce qui aide dans une situation similaire dans les gestionnaires http génériques [.ashx]) - pas de chance. J'utilise le mode simple d'état de session InProc. Le taux de change doit être spécifique à l'utilisateur.

Que puis-je faire?

Je travaille avec: développement web, .Net 4, VB.net


étape par étape:
page_load (en .aspx)
dim objSearch neuf searchclass ()
sortie dim = objSearch.renderProductsFound()

puis en objSearch.renderProductsFound:
lstProductList.Add (objProduct (1))
...
lstProductList.Add (objProduct (n))

dim x = Du produit En lstProductList.AsParallel
Trier par Product.Price.GrossPrice descendant Sélectionnez un produit

En Product.Price.GrossPrice Obtenez:
me.NetPrice retour + me.VatAmount

En Product.Price.NetPrice Get:
retour NetBasePrice session * ("exchange_rate")

Encore une fois, le code simplifié, trop coller ici. Fonctionne très bien si je déplie la requête dans les boucles For.

+1

L'écrivez-vous comme ça? Parce que vous avez besoin de lancer n'importe quel élément de Session dans le bon type avant de l'utiliser. –

+0

non, c'est juste simplifié. Le calcul est en réalité beaucoup plus compliqué que cela et il y a beaucoup de vérifications pour Nothing, les conversions de type (CDec dans le cas ci-dessus) et les valeurs par défaut. – Dima

+1

Pour comprendre si HttpContext est disponible, veuillez expliquer comment vous appelez ce code. Est-ce d'un .aspx ou d'autre chose? –

Répondre

0

Je ne sais pas exactement comment fonctionne HttpContext.Current, mais je ne serais pas surpris si cela ne fonctionnerait que sur le thread principal qui traite la requête HTTP. Cela signifierait que vous ne pouvez pas l'utiliser sur d'autres threads. Lorsque PLINQ exécute la requête, il sélectionne des threads aléatoires dans le pool de threads et évalue les prédicats dans la requête à l'aide de ces threads, ce qui explique peut-être pourquoi votre requête ne fonctionne pas.

Si les besoins propriété GrossPrice accéder qu'à une seule chose de l'état de la session, il devrait être assez facile de changer à une méthode et passer la valeur de l'état de la session comme argument:

Dim rate = Session("exchange_rate") 
Dim x = From product In lstProductList.AsParallel 
     Order By product.Price.GetGrossPrice(rate) Descending 
     Select product 

Selon l'endroit où vous utiliserez x plus tard, vous pouvez également ajouter un appel à ToList pour forcer l'évaluation de la requête (sinon elle pourra être exécutée paresseusement plus tard), mais je pense que la modification que j'ai décrite ci-dessus devrait la réparer.

+0

Tomas, merci. Je pensais dans le même sens en ce qui concerne les threads parallèles n'ayant pas accès à HTTPContext et en utilisant des variables locales, seulement je dois sérialiser cette classe à JSON plus tard - qui ne fonctionnerait pas avec les méthodes. La meilleure idée que j'ai jusqu'à maintenant est d'avoir GrossPrice comme propriété et GetGrossPrice comme méthode - utilisez le premier pour la sérialisation et utilisez ce dernier dans pLinq, il doit y avoir une solution plus éloquente ... – Dima

0

Vous devriez vraiment lire les valeurs hors état de session et dans les variables locales dont vous avez besoin dans l'instruction LINQ. Sinon, vous accédez à l'instance NameValueCollection à chaque fois pour chaque élément de chaque thread lorsque la valeur est essentiellement constante.

+0

vous avez raison, Je n'y ai pas vraiment réfléchi de ce côté. Puisque j'utilise plinq pour obtenir des performances maximales, cela n'a pas de sens d'utiliser Session dans la requête. – Dima