11

我的加入看起来像这样:

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

但是当 user.imageId 为空时,slick 在运行时失败

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

将产量更改为

} yield (user, image.?)

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

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

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

4

3 回答 3

8

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

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) 应该有助于减少一些样板文件。

于 2013-02-21T08:56:03.450 回答
8

使用下面的代码,您可以这样说: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
    } 
}
于 2013-11-30T10:20:16.210 回答
1

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

看到.? 调用定义?以及mapOption 的定义

于 2013-09-28T04:39:20.923 回答