Question

Prenez cette simple requête C # LINQ et imaginez que db.Numbers est une table SQL avec une colonne Number :

var result = 
    from n in db.Numbers
        where n.Number < 5
        select n.Number;

Ceci fonctionnera très efficacement dans C # , car il génère une requête SQL similaire à

.
select Number from Numbers where Number < 5 

Ce que ne le fait pas , c’est de sélectionner tous les numéros de la base de données, puis de les filtrer dans C # , comme il est possible qu’il apparaisse à faire au début.

Python prend en charge une syntaxe similaire:

result = [n.Number for n in Numbers if n.Number < 5]

Mais c'est la clause if qui filtre ici du côté client, plutôt que du côté serveur, ce qui est beaucoup moins efficace.

Y at-il quelque chose d'aussi efficace que LINQ dans Python ? (J'évalue actuellement Python et IronPython et Boo , donc une réponse qui fonctionne dans n'importe lequel de ces langages convient parfaitement.)

Était-ce utile?

La solution

Je pense que, une fois terminée, IronPython 2.0 sera compatible LINQ (voir ce fil pour un exemple de discussion). Pour le moment, vous devriez pouvoir écrire quelque chose comme:

Queryable.Select(Queryable.Where(someInputSequence, somePredicate), someFuncThatReturnsTheSequenceElement) 

Quelque chose de mieux aurait pu figurer dans IronPython 2.0b4 - il y a beaucoup de discussion en cours sur la gestion des conflits de noms.

Autres conseils

sqlsoup dans sqlalchemy vous offre la solution la plus rapide en python si vous le souhaitez. un clair (ish) une doublure. Regardez la page pour voir.

Cela devrait être quelque chose comme ...

result = [n.Number for n in db.Numbers.filter(db.Numbers.Number < 5).all()]

LINQ est une fonctionnalité de langage de C # et VB.NET. C'est une syntaxe spéciale reconnue par le compilateur et traitée spécialement. Il dépend également d'une autre fonctionnalité du langage appelée arborescence des expressions.

Les

arbres d’expression diffèrent peu du fait qu’ils ne constituent pas une syntaxe particulière. Elles sont écrites comme toute instanciation de classe, mais le compilateur les traite spécialement sous les couvertures en transformant un lambda en instanciation d’une exécution arbre de syntaxe abstraite . Ceux-ci peuvent être manipulés au moment de l'exécution pour générer une commande dans une autre langue (SQL).

Les compilateurs C # et VB.NET utilisent la syntaxe LINQ et le convertissent en lambdas, puis transmettent ces informations à des instanciations de l’arbre des expressions. Ensuite, il y a un tas de classes de framework qui manipulent ces arbres pour produire du SQL. Vous pouvez également trouver d’autres bibliothèques, produites par des tiers et tierces, proposant des "fournisseurs LINQ", qui intègrent un processeur AST différent pour produire quelque chose à partir de LINQ que SQL.

Un des obstacles à la réalisation de ces tâches dans une autre langue est donc la question de savoir si elles prennent en charge la construction / manipulation AST au moment de l'exécution. Je ne sais pas s'il existe des implémentations de Python ou de Boo, mais je n'ai jamais entendu parler de telles fonctionnalités.

Observez attentivement SQLAlchemy . Cela peut probablement faire beaucoup de ce que vous voulez. Il vous donne la syntaxe Python pour le SQL ancien qui s'exécute sur le serveur.

Un facteur clé pour LINQ est la capacité du compilateur à générer des arbres d’expression. J'utilise une macro dans Nemerle qui convertit une expression Nemerle donnée en un objet d'arbre d'expression. Je peux ensuite transmettre cela aux méthodes d'extension Where / Select / etc sur IQueryables. Ce n'est pas tout à fait la syntaxe de C # et VB, mais c'est assez proche pour moi.

J'ai reçu la macro Nemerle via un lien sur ce message: http://groups.google.com/group/nemerle-dev/ browse_thread / thread / 99b9dcfe204a578e

Il devrait être possible de créer une macro similaire pour Boo. Cela demande cependant beaucoup de travail, étant donné le grand nombre d'expressions possibles que vous devez prendre en charge. Ayende a donné une preuve de concept ici: http://ayende.com/Blog/archive/2008/ 08/05 / Ugly-Linq.aspx

Boo prend en charge les expressions de générateur de liste utilisant la même syntaxe que python. Pour plus d'informations à ce sujet, consultez la documentation Boo sur les expressions de générateur et Liste des compréhensions .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top