【问题标题】:Slick left outer join fetching whole joined row as option光滑的左外连接获取整个连接行作为选项
【发布时间】:2013-02-20 21:33:41
【问题描述】:

我的加入看起来像这样:

def byIdWithImage = for {
    userId <- Parameters[Long]
    (user, image) <- Users leftJoin RemoteImages on (_.imageId === _.id) if user.id === userId
} yield (user, image)

但当 user.imageId 为 null 时,slick 在运行时会失败

[SlickException: 读取 RemoteImage.url 列的 NULL 值]

将产量改为

} yield (user, image.?)

给我一​​个编译时异常,它只适用于个别列

找不到 scala.slick.lifted.TypeMapper[image.type] 类型的证据参数的隐含值

会有不同的方法来完成我在这里尝试做的事情吗? (在单个查询中)

【问题讨论】:

标签: scala left-join option slick


【解决方案1】:

使用下面的代码,您可以这样写:yield (user, image.maybe)

case class RemoteImage(id: Long, url: URL)

class RemoteImages extends Table[RemoteImage]("RemoteImage") {
    def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
    def url = column[URL]("url", O.NotNull)
    def * = id.? ~ url <> (RemoteImage.apply _, RemoteImage.unapply _)

    def maybe = id.? ~ url.? <> (applyMaybe,unapplyBlank)

    val unapplyBlank = (c:Option[RemoteImage])=>None        

    val applyMaybe = (t: (Option[Long],Option[URL])) => t match {
        case (Some(id),Some(url)) => Some(RemoteImage(Some(id),url))
        case _ => None
    } 
}

【讨论】:

    【解决方案2】:

    在我的脑海中,我会使用自定义映射投影。像这样的:

    case class RemoteImage(id: Long, url: URL)
    
    def byIdWithImage = for {
        userId <- Parameters[Long]
        (user, image) <- Users leftJoin RemoteImages on (_.imageId === _.id) if user.id === userId
    } yield (user, maybeRemoteImage(image.id.? ~ image.url.?))
    
    def maybeRemoteImage(p: Projection2[Option[Long], Option[URL]]) = p <> ( 
      for { id <- _: Option[Long]; url <- _: Option[URL] } yield RemoteImage(id, url),
      (_: Option[RemoteImage]) map (i => (Some(i id), Some(i url)))
    )
    

    使用 scalaz(及其ApplicativeBuilder)应该有助于减少一些样板文件。

    【讨论】:

    • 谢谢,如果 slick 能为这种情况提供帮助,那就太好了
    【解决方案3】:

    我在我的 play-slick 示例应用中为此集成了帮助程序,您只需调用 image.?

    请参阅the .? calls、the definition of ? 和 the definition of mapOption。

    【讨论】:

    • 这会成为 slick 2.0 的一部分吗?
    • 不是这个实现,但可能我们的代码生成器会生成所需的?方法。所以在某种程度上,可能是的。
    猜你喜欢
    • 2013-12-21
    • 1970-01-01
    • 2017-04-23
    • 1970-01-01
    • 2016-04-20
    • 2013-09-03
    • 2010-10-21
    • 2011-10-01
    • 1970-01-01
    相关资源
    最近更新 更多