2013-02-05 3 views
15

Ich verwende SLICK 1.0.0-RC2. Ich habe die folgenden zwei Tabellen Direktion und Servicebereich definiert, in der Direktion ein Eins-zu-Beziehung mit Servicebereich hatSLICK So definieren Sie bidirektionale 1: n-Beziehung für die Verwendung in der Fallklasse

case class Directorate(dirCode: String, name: String) 

object Directorates extends Table[Directorate]("DIRECTORATES") { 

    def dirCode = column[String]("DIRECTORATE_CODE", O.PrimaryKey) 

    def name = column[String]("NAME") 

    def * = dirCode ~ name <> (Directorate, Directorate.unapply _) 
} 

case class ServiceArea(areaCode: String, dirCode: String, name: String) 

object ServiceAreas extends Table[ServiceArea]("SERVICE_AREAS") { 

    def areaCode = column[String]("AREAE_CODE", O.PrimaryKey) 

    def dirCode = column[String]("DIRECTORATE_CODE") 

    def name = column[String]("NAME") 

    def directorate = foreignKey("DIR_FK", dirCode, Directorates)(_.dirCode) 

    def * = areaCode ~ dirCode ~ name <> (ServiceArea, ServiceArea.unapply _) 
} 

Um die Direktion Fall-Klasse, die in meiner Play-Anwendung Formular Ich versuche, die Direktion Fall Klasse neu definieren müssen a Seq von ServiceAreas, die mit dieser Direktion verwandt sind.

Mein Problem ist jetzt mit der Tabelle Tabelle Projektion.

def serviceAreas = (for { a <- ServiceAreas 
         if (a.dirCode === dirCode) 
        } yield (a)).list map { 
         case t: ServiceArea => t 
        } 

so, dass ich so etwas wie

def * = dirCode ~ name ~ serviceAreas <> (Directorate, Directorate.unapply _) 

versuchen kann, aber dies kann nicht nicht wie serviceAreas nur einen Weg geht: Ich habe eine Methode in Direktionen zu schaffen versucht.

Es scheint mir sinnvoll, dass die Fallklasse der Direktion ein nützliches Domänenobjekt sein sollte, das die zugehörigen ServiceAreas enthalten kann.

Ich frage mich, wie ich die umgekehrte Beziehung durchqueren sollte, so dass Direktion Tabelle Projektion funktioniert.

Antwort

15

Ich bin sicher, dass es eine elegantere Lösung, aber das sollte es tun:

import scala.slick.driver.H2Driver.simple._ 
import Database.threadLocalSession 

object SlickExperiments2 { 

    Database.forURL("jdbc:h2:mem:test1", driver = "org.h2.Driver") withSession { 

    (Directorates.ddl ++ ServiceAreas.ddl).create 

    case class Directorate(dirCode: String, name: String) { 
     def serviceAreas: Seq[ServiceArea] = (for { 
     a <- ServiceAreas 
     if (a.dirCode === dirCode) 
     } yield (a)).list 
    } 

    object Directorates extends Table[Directorate]("DIRECTORATES") { 

     def dirCode = column[String]("DIRECTORATE_CODE", O.PrimaryKey) 

     def name = column[String]("NAME") 

     def * = dirCode ~ name <> (Directorate, Directorate.unapply _) 
    } 

    case class ServiceArea(areaCode: String, dirCode: String, name: String) 

    object ServiceAreas extends Table[ServiceArea]("SERVICE_AREAS") { 

     def areaCode = column[String]("AREAE_CODE", O.PrimaryKey) 

     def dirCode = column[String]("DIRECTORATE_CODE") 

     def name = column[String]("NAME") 

     def directorate = foreignKey("DIR_FK", dirCode, Directorates)(_.dirCode) 

     def * = areaCode ~ dirCode ~ name <> (ServiceArea, ServiceArea.unapply _) 
    } 

    Directorates.insert(Directorate("Dircode", "Dirname")) 

    ServiceAreas.insertAll(ServiceArea("a", "Dircode", "A"), ServiceArea("b", "Dircode", "B")) 

    val sa = (for{ 
    d <- Directorates 
    } yield d).list map { case t: Directorate => t.serviceAreas} 

    println(sa) 
    }            
//> List(List(ServiceArea(a,Dircode,A), ServiceArea(b,Dircode,B))) 
} 
+1

Dank, dass viel mehr Sinn macht serviceAreas Methode auf den Fall der Klasse hinzuzufügen. Es scheint der Weg zu sein, die inverse Seite einer Eins-zu-Viele-Beziehung zu durchqueren. –

+0

Schön! Ich habe diesen Ansatz nicht berücksichtigt. Aber für mich ist der Aufbau von ServiceArea in der Fallklasse der Direktion ('Fall t: ServiceArea => ServiceArea (t.areaCode, t.DirCode, t.name)') sorta riecht. Gibt es eine Möglichkeit, das Konstruktions-Mapping zu nutzen, das bereits auf 'ServiceAreas' existiert? –

+0

@ JonathanWilson Gut entdeckt - das bisschen Code waren Überbleibsel eines Ausschneidens und Einfügens. Für automatisch generierte Schlüssel muss ich manchmal Klassen ohne eine ID konstruieren, und diese Linie kam wahrscheinlich von einem solchen Ort. Danke - ich habe es entfernt ;-) – Jack