Where successifs
-
jeudi 16 février 2012 11:02
Je rencontre un problème avec des filtres "where" qui quand appliques successivement retournent un dataset vide mais fonctionnent parfaitement quand ils sont combinées
Ceci fonctionne :
Dim Tlog = From L In db.MyLogs Select L Dim s_level As String = "warning" Dim s_source As String = "web" Tlog = Tlog.Where(Function(x) x.Level = s_level).Where(Function(x) x.Source = s_source)
Cala non :
Tlog = Tlog.Where(Function(x) x.Level = s_level) Tlog = Tlog.Where(Function(x) x.Source = s_source)
N’étant pas expert en la matière je ne sais pas si c’est normal ou pas. Pourriez-vous m’éclairer.
En vous remerciant d’avance
BB
Toutes les réponses
-
jeudi 16 février 2012 12:13
Bonjour,
J'ai fait un test mais je ne vois aucune différence dans le SQL généré. Utiliser SQL Server Profiler ou éventuellement (si vous utiliser un "ObjectContext") :
Debug.WriteLine(CType(Tlog,System.Data.Objects.ObjectQuery).ToTraceString)
Pour l'instant j'ai l'impression que le problème est ailleurs... Vérifier peut-être le "Count" immédiatement après avoir défini votre requête. Vous utilisez vraiment un "DataSet" ou vous parlez de la liste retournée par la requête.
Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".
-
jeudi 16 février 2012 17:02
Bonjour Partice Scribe,
Je parle de la liste retournée par la requête, pas d’un objet dataset.
Il est vrai que j’ai enlevé les lignes de leur contexte pour que ça ne prenne pas trop de place. Et l’exemple que j’ai donné fonctionne dans les 2 cas. Le fait que vos essais aient donnée le bon résultat m’a incité à chercher autours et j’ai trouvé la raison du dysfonctionnement.
Je l’explique ci-dessous pour ceux que ça intéresse, la vraie séquence était proche de celle-ci:
Function Logs(RFR As FormCollection) As ActionResult Dim Tlog = From l In db.MbeLogs Select l Dim s As String = String.Empty IfNotString.IsNullOrWhiteSpace(RFR("Levels")) Then s=RFR("Levels") Tlog = Tlog.Where(Function(x) x.Level = s) EndIf IfNotString.IsNullOrWhiteSpace(RFR("Source")) Then s=RFR("Source") Tlog = Tlog.Where(Function(x) x.Source = s) EndIf Return View(Tlog.ToList)
Cette façun de faire ne marche pas car l’exécution de la requête est réalisée lors de la transformation .ToList, à ce moment-là la variable S a la dernière valeur qu’elle a reçu. Cela doit revenir à écrire quelque chose comme … WHERE x.Level=S AND x.Source=s ou S n'a aucun sens pour Level
La solution consiste à faire en sorte que les S soient distincts. Soit en créant des variables distinctes pour chaque élément de comparaison soit en instanciant la variable S dans le bloc Then comme ci-dessous.
If Not String.IsNullOrWhiteSpace(RFR("Levels")) Then Dim s As String =RFR("Levels") Tlog = Tlog.Where(Function(x) x.Level = s) End IfCurieusement cela marche, vous, vous ne pouvez pas utiliser la variable S à l’extérieur du block Then mais Linq s’en accommode fort bien.
Merci beaucoup pour votre aide.
-
jeudi 16 février 2012 17:46
Exact. Le point clé est que l'on ne fait que *définir* une requête. Elle sera exécutée au moment ou l'on commence à énumérer les résultats que retournerait cette requête. Toutefois Function(x) a accès au contexte dans lequel elle a été déclarée et peut donc accéder à s même si s est définie dans un bloc "if"...
Please always mark whatever response solved your issue so that the thread is properly marked as "Answered".

