我们可以使用Python或者Boo等语言进行类似LINQ的查询吗?
以这个简单的CLINQ查询为例,假设'db.Numbers'是一个带有一列Number的SQL表:
var结果=
从db.Numbers中的n开始
其中n.Number <5
选择n.Number;
这将在C#中非常有效地运行,因为它会生成SQL查询,例如"从Numbers <5的Numbers中选择Numbers"。它不执行的操作是从数据库中选择所有数字,然后使用C#对其进行过滤,就像最初看起来那样。
Python支持类似的语法:
结果= [如果n.Number <5,则为n中的n.Number]
但是,这里的" if"子句在客户端而不是服务器端进行过滤,效率低得多。
有没有像LINQ一样高效的工具? (我目前正在评估Python与IronPython与Boo,因此可以使用任何一种语言的答案都可以)。
解决方案
仔细看看SQLAlchemy。这可能可以完成我们想要的大部分工作。它为我们提供了在服务器上运行的普通SQL的Python语法。
LINQ是Cand VB.NET的语言功能。这是编译器可以识别并经过特殊处理的特殊语法。它也依赖于称为表达式树的另一种语言功能。
表达式树有些不同,因为它们不是特殊的语法。它们的编写与其他任何类的实例化一样,但是编译器确实通过将lambda转换为运行时抽象语法树的实例化,对它们进行了特别的处理。可以在运行时对它们进行操作,以产生另一种语言(即SQL)的命令。
Cand VB.NET编译器采用LINQ语法,并将其转换为lambda,然后将其传递给表达式树实例。然后是一堆框架类,它们操纵这些树来生成SQL。我们还可以找到提供" LINQ提供程序"的其他库,包括MS生产的第三方库和第三方库,这些库基本上会弹出一个不同的AST处理程序,以从LINQ生成除SQL之外的其他内容。
因此,用另一种语言来做这些事情的一个障碍是他们是否支持运行时AST的构建/操作的问题。我不知道Python或者Boo的任何实现都可以,但是我还没有听说过任何此类功能。
我相信IronPython 2.0完成后,它将具有LINQ支持(有关示例讨论,请参见此线程)。现在,我们应该可以编写如下内容:
Queryable.Select(Queryable.Where(someInputSequence, somePredicate), someFuncThatReturnsTheSequenceElement)
更好的东西可能已经融入了IronPython 2.0b4中,目前有很多关于如何处理命名冲突的讨论。
sqlalchemy中的sqlsoup为我们提供了python中最快的解决方案,我想如果我们想要一个清晰的(衬里)衬板。看页面看。
应该是...
result = [n.Number for n in db.Numbers.filter(db.Numbers.Number < 5).all()]
LINQ的关键因素是编译器生成表达式树的能力。
我在Nemerle中使用了一个宏,该宏将给定的Nemerle表达式转换为Expression树对象。
然后,我可以将其传递给IQueryables的Where / Select / etc扩展方法。
它不是Cand VB的语法,但对我来说足够接近。
我通过这篇文章的链接获得了Nemerle宏:
http://groups.google.com/group/nemerle-dev/browse_thread/thread/99b9dcfe204a578e
应该可以为Boo创建类似的宏。考虑到我们需要支持的大量可能的表达式,这需要大量的工作。
Ayende在这里给出了概念证明:
http://ayende.com/Blog/archive/2008/08/05/Ugly-Linq.aspx
Boo使用与python相同的语法支持列表生成器表达式。有关这方面的更多信息,请查看有关生成器表达式和列表推导的Boo文档。