C#: Est-il possible de déclarer une variable locale à une méthode anonyme?
Est possible d'avoir une variable locale dans une anonyme méthodes c#, c'est à dire dans le code suivant, je voudrais effectuer le décompte qu'une fois.
IQueryable<Enquiry> linq = db.Enquiries;
if(...) linq = linq.Where(...);
if(...) linq = linq.Where(e =>
(x <= (from p in db.Orders where p.EnquiryId == e.Id select p).Count() &&
(from p in db.Orders where p.EnquiryId == e.Id select p).Count() <= y));
if(...) linq = linq.Where(...);
var result = (from e in linq select e);
Est-il un "let" pour les fonctions anonymes?
Mise à jour:
Notez que je suis en ajoutant plusieurs clauses where après cette déclaration, donc je ne peux pas fermer avec un select.
/Niels
Avez-vous essayé ceci: var q = où l dans linq soit ct = (p) en db.Les ordres p.EnquiryId == e.Id select p).Count() sélectionnez l;
vous devez commencer avec " de "au lieu de "où". Alors la variable e est appelée, mais elle n'est pas définie n'importe où. Aussi ct défini, mais il n'est pas utilisé. Enfin, même si où a été changé à partir, le résultat devrait contenir les mêmes que linq (l'entrée). En dehors de cela, c'est génial.
vous devez commencer avec " de "au lieu de "où". Alors la variable e est appelée, mais elle n'est pas définie n'importe où. Aussi ct défini, mais il n'est pas utilisé. Enfin, même si où a été changé à partir, le résultat devrait contenir les mêmes que linq (l'entrée). En dehors de cela, c'est génial.
OriginalL'auteur Niels Bosma | 2008-12-15
Vous devez vous connecter pour publier un commentaire.
J'ai un problème similaire. La solution est de créer une expression personnalisée arbre de génération de méthode.
J'ai posé ma question sur MSDN-forums. Veuillez voir la question et la réponse ici: Réutilisation d'Où les expressions.
Cela peut vous donner une idée sur la manière de procéder, mais je dois avouer que la coutume des arbres d'expression ne sont pas pour les timides 😉
OriginalL'auteur Torben Rahbek Koch
Oui, pourquoi pas?! Après tout, c'est une fonction anonyme!
Exemple:
Ou alternativement:
Sorte que votre code peut être écrit comme:
Mise à JOUR: afin De clarifier les choses à propos du commentaire, il est important de connaître la différence entre les méthodes anonymes et les expressions lambda. Une méthode anonyme est juste comme une méthode normale, sans un nom explicite. Lors de la compilation, le compilateur génère un mode normal avec un nom bizarre pour vous, au lieu, donc il n'aura pas de limitations particulières. Cependant, une représentation d'une méthode anonyme est une expression lambda. Les expressions Lambda peut être interprétée de différentes façons. Le premier est un délégué. De cette façon, ils sont égaux à une méthode anonyme. La deuxième est une expression de l'arbre. De cette façon, est normalement utilisé par LINQ to SQL et quelques autres fournisseurs LINQ. Ils n'exécutent pas votre expression directement par tous les moyens. Ils analyser comme une expression de l'arbre et de l'utilisation de l'arbre comme données d'entrée pour générer l'équivalent de l'instruction SQL à exécuter sur le serveur. Il n'est pas exécuté comme une méthode et il n'est pas considéré comme une méthode anonyme. Dans ce cas, vous ne pouvez pas définir une variable locale comme il n'est pas possible d'analyser le lambda comme une expression de l'arbre.
Le problème est que le demandeur n'a pas une phrase correctement à la question - qu'il veut vraiment savoir à ce sujet dans le contexte d'une Linq to SQL de la requête, et non pas une requête Linq to Objects. Suce que nous avons à traiter différemment des autres, mais là vous l'avez.
"Dans ce cas [Linq to SQL], vous ne pouvez pas définir une variable locale comme il n'est pas possible de l'analyser comme une arborescence d'expression." - sauf que vous pouvez, si vous lisez ma réponse à cette question.
Votre affirmation de l'absence de limites est incorrect. Il existe une variété de limitations sur les expressions lambda/fonctions anonymes. Par exemple, essayez d'utiliser de la base.Quelque chose en C# fonction anonyme. Selon votre version, vous obtiendrez un avertissement ou l'échec de la compilation
Dans votre exemple, vous n'êtes pas définir une variable locale dans une lambda expression du corps. En utilisant laissez, vous n'avez pas défini une variable locale dans votre lambda. Je parle des expressions lambda et non les caractéristiques de LINQ to SQL.
OriginalL'auteur Mehrdad Afshari
Oui, vous pouvez faire exactement ce que vous voulez, dans Linq to objects et Linq to SQL.
Il y a un
let
dans Linq, vous permettant de donner un nom à un résultat intermédiaire dans le milieu de votre requête, tout comme vous le souhaitez. Basé sur votre exemple:Par la manière, je pense qu'il y avait quelque chose dans la syntaxe erronée au sujet de votre exemple d'origine, ce qui est plus facile à repérer quand le
count
est juste un nom:J'ai ajouté un 'select e' ci-dessus pour créer l'exemple de la corriger. Mais que voulez-vous dire que vous ne pouvez pas mettre fin à la requête? Vous avez à la fin avec quelque chose que les membres de ce qu'il produit. Vous pouvez mettre plusieurs conditions de la clause where - il suffit d'ajouter plus des deux déjà là.
OriginalL'auteur Daniel Earwicker
Si vous êtes à l'aide de Linq to SQL, vous ne serez pas en mesure d'utiliser Mehrdad Afshari de réponse. Vos expressions LINQ doivent être des Arbres d'Expression, et ceux qui ne prennent pas en charge le délégué anonyme de la syntaxe.
Ni vous serez en mesure de créer votre délégué ailleurs et l'appeler à partir de l'intérieur de la lambda - Linq to SQL ne permet certaines opérations qui doivent être effectuées dans le corps de la requête, et d'appeler un délégué n'est pas l'un d'eux.
Votre meilleur pari, en supposant que vous êtes à l'aide de Linq to SQL (tel qu'il apparaît, compte tenu de votre exemple), est de faire baisser le nombre dans une requête, puis capturez le nombre de variables dans la requête qui nécessite le comte.
OriginalL'auteur Erik Forbes
La méthode prend un Func donc ce que vous êtes de passage dans la il y dans la deuxième partie de l'ins en fait pas une méthode, mais juste une expression booléenne. Ma suggestion serait d'avoir une méthode qui retourne un bool, qui prend en paramètres à utiliser vous avez besoin et à votre appel à la méthode que vous venez de faire quelque chose de ce genre(p=> MyMethod(p,...))
OriginalL'auteur BFree
Avec un peu de fond dans le Schéma, vous savez que " let " est juste la syntaxe de sucre pour la définition d'un lambda et de l'appeler.
Donc, avec cette connaissance, vous permet de voir comment il peut être fait.
Comme un bonus, il ressemble Régime de trop 🙂
Avertissement: je n'ai pas tester cet extrait de code, mais il n'y a aucune raison qu'il ne devrait pas travailler. Personnellement, je voudrais juste utiliser le " laissez-les construire fourni dans LINQ.
Mise à jour:
Il ne fonctionne pas... 🙁
le problème est que la question est à propos de LINQ to SQL. Malheureusement, ce n'est indiquée par la balise, pas n'importe où dans le titre ou la description. Le "let" mot-clé dans LINQ n'est pas la même chose qu'un invoquées directement lambda. C'est une sélection qui produit une séquence de paires d'entrées/sorties.
OriginalL'auteur