2013-02-20 6 views
11

Mein kommen sieht wie folgt aus:Slick linke äußere Verknüpfung holen ganze Reihe verbunden als Option

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

aber glatt versagt während der Laufzeit, wenn user.imageId null ist

[SlickException: für NULL-Wert lesen Spalte RemoteImage.url]

Ändern der Ausbeute zu

gibt mir eine Kompilierung Ausnahme, es funktioniert nur auf einzelne Spalten

nicht impliziten Wert für Beweise Parameter des Typs scala.slick.lifted.TypeMapper [image.type]

finden konnten,

Würde es einen anderen Weg geben, um das zu erreichen, was ich hier versuche? (in einer einzigen Abfrage)

+1

Etwas Hälfte in Slick fixiert 2,0 => http://slick.typesafe.com/talks/ 2013-12-03_Scala-eXchange/2013-12-03_Patterns-for-Slick-Datenbank-Anwendungen-Scala-eXchange.pdf – Somatik

+0

im Zusammenhang mit http://StackOverflow.com/Questions/20386593/ – cvogt

Antwort

7

Mit dem folgenden Code können Sie es wie setzen können: Ausbeute (Benutzer, 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 
    } 
} 
8

Aus der Spitze meines Kopfes würde ich eine benutzerdefinierte projizierte Projektion verwenden. Etwas wie folgt aus:

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

Mit scalaz (und seine ApplicativeBuilder) sollten einige dieser vorformulierten reduzieren.

+6

danke, wäre nett, wenn glatt würde einen Helfer für diesen Fall zur Verfügung stellen – Somatik

1

integrierten I Helfer für das in meinem Spiel-Slick Beispiel-App, die Ihnen erlauben, nur image.?

Siehe the .? calls, the definition of ? und the definition of mapOption zu nennen.

+0

wird dies ein Teil von Slick 2.0 sein? – Somatik

+0

Nicht diese Implementierung, aber wahrscheinlich wird unser Code-Generator die erforderliche generieren? Methoden. Also in gewisser Weise, wahrscheinlich ja. – cvogt