在Slick中是否可以定义动态投影?

4

我有一个连接多个表的查询。我希望能够将应该检索哪些字段参数化(有时是复杂的SQL Postgis函数)。假设初始查询是这样构建的:

def buildQuery() = for {
  c <- coffees if c.price > 9.0
  s <- c.supplier
} yield (c.name, s.name)

现在我希望其中一个产生的值取决于我的参数,所以示例将变为:
val param = true
def buildQuery() = for {
  c <- coffees if c.price > 9.0
  s <- c.supplier
} yield (c.name, if (param) s.name else null)

这样的代码是行不通的,Slick内部会抛出NullPointerException异常。 是否有合理的方法可以根据输入参数动态构建yield部分?
1个回答

0

看起来我们无法通过这个DSL实现“null”元素。此外,它适用于Column[]但不适用于表格,就像在这种情况下:使用对s的条件yield(c.name,s) - kciesielski
你可以使用 '... else LiteralNode("null")' 来实现 "null"。 - tfh
你是对的,在2.1版本中,这被限制为使用Column类型作为... def Then(res: Column[T])... (参见:https://github.com/slick/slick/blob/2.1/src/main/scala/scala/s/lifted/Case.scala)。另一方面,Slick主分支将类型限制为`Rep`(参见:https://github.com/slick/slick/blob/master/src/main/scala/scala/slick/lifted/Case.scala),它是`Column`和`Table`的基础类型。在slick主分支中应该可以使用`s`上的条件来应用更改。 - tfh
我尝试在Slick Activator中应用此代码(依赖项已更新为2.2.0-SNAPSHOT),但是这段代码:val cond: Boolean = true; val joinQuery = for { c <- coffees if c.price > 9.0; s <- c.supplier } yield (c.name, Case If cond Then s.name Else LiteralNode("null"))会产生相当多的编译错误。 - kciesielski
尝试使用Slick的Case DSL实现类似于 if (param) s.name.? else null.? 的功能。 - cvogt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接