Slick left outer join извлечение всей соединенной строки в качестве опции

мое соединение выглядит так:

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

но Слик не во время выполнения, когда пользователь.imageId имеет значение null

[SlickException: чтение значения NULL для столбца RemoteImage.URL-адреса]

изменение выхода на

} yield (user, image.?)

дает мне исключение времени компиляции, оно работает только на отдельных столбцах

не удалось найти неявное значение для доказательства параметр типа скала.скользкий.поднятый.TypeMapper[изображение.type]

будет ли другой способ, чтобы выполнить то, что я пытаюсь сделать здесь? (в одном запросе)

3 ответов


С кодом ниже, вы можете положить его как: yield (пользователь, изображение.может быть)

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
    } 
}

С верхней части моей головы я бы использовал пользовательскую отображенную проекцию. Что-то вроде этого:--3-->

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) должно помочь уменьшить некоторые из этих шаблонов.


я интегрировал помощников для этого в моем приложении play-slick example, которые позволяют вам просто позвонить image.?

посмотреть the .? звонки, определение ? и определение mapOption.