我的加入看起来像这样:
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]
类型的证据参数的隐含值
有没有不同的方法来完成我在这里尝试做的事情? (在单个查询中)
答案 0 :(得分: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
)应该有助于减少一些样板。
答案 1 :(得分:7)
使用下面的代码,你可以这样说: 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 :(得分:1)
我在我的Play-slick示例应用程序中为此集成了帮助程序,您只需拨打image.?
请参阅the .? calls,the definition of ?和the definition of mapOption。