问题 光滑左外连接获取整个连接行作为选项


我的加入看起来像这样:

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

但是当user.imageId为null时,浮动在运行时失败

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

将收益率改为

} yield (user, image.?)

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

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

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


4819
2018-02-20 21:33


起源

在光滑的2.0 =>中固定了一半 slick.typesafe.com/talks/2013-12-03_Scala-eXchange/... - Somatik
相关 stackoverflow.com/questions/20386593 - cvogt


答案:


使用下面的代码,你可以这样说: 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
    } 
}

7
2017-11-30 10:20





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

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


8
2018-02-21 08:56



谢谢,如果光滑的话会为这种情况提供帮助,那就太好了 - Somatik


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

看到 。?电话定义? 和 mapOption的定义


1
2017-09-28 04:39



这将是光滑2.0的一部分吗? - Somatik
不是这个实现,但可能我们的代码生成器会生成所需的?方法。所以在某种程度上,可能是的。 - cvogt