作为ScalaQuery的作者,我没有太多补充到斯蒂尔加的解释。在Scala中缺少的LINQ部分确实是表达式树。这就是为什么ScalaQuery对Column和Table类型执行所有计算而不是这些实体的基本类型的原因。
您声明一个表作为表对象与它的列的突起(元组),例如:
class User extends Table[(Int, String)] {
def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
def name = column[String]("name")
def * = id ~ name
}
User.id和User.name现在类型列[INT]和柱[字符串] 分别。所有计算都是在Query monad中执行的(这是数据库查询的一种比数据库查询更自然的表示,而不是必须从其创建的SQL语句)。以下面的查询:
val q = for(u <- User if u.id < 5) yield u.name
一些隐式转换后和脱糖这样的语句:
val q:Query[String] =
Query[User.type](User).filter(u => u.id < ConstColumn[Int](5)).map(u => u.name)
过滤器和映射方法没有检查他们的论据是表达式树以构建查询,他们只是运行它们。正如你可以从这些类型中看到的那样,表面上看起来像“u.id:Int < 5:Int”实际上是“u.id:Column[Int] < u.id:Column[Int]”。运行此表达式会产生查询AST,如Operator.Relational(“<”,NamedColumn(“user”,“id”),ConstColumn(5))。同样,查询单元的“过滤器”和“映射”方法实际上并不执行过滤和映射,而是建立一个描述这些操作的AST。
QueryBuilder然后使用此AST为数据库构建实际的SQL语句(使用DBMS特定的语法)。
ScalaQL采用了一种替代方法,它使用编译器插件直接处理表达式树,确保它们只包含数据库查询中允许的语言子集,并静态构造查询。
非常好的问题被使用。作为一个对函数式语言感兴趣的人,我很好奇Scala在这方面提供了什么,以及如何/如何将LINQ样式的支持作为库来构建。请提出这个问题。 – Stilgar 2010-12-06 12:17:36
我知道,Scala的团队认为有关集成像LINQ,但我想这还需要一段时间... – Landei 2010-12-06 15:22:32
UPDATE:这些天你应该看看斯利克 - https://github.com/slick – Jack 2012-07-16 09:54:26