2013-03-12 13 views
6

Ho una tabella come questa:Come definire la chiave esterna opzionale in Slick?

object Addresses extends Table[AddressRow]("address") { 
    def id = column[Int]("id", O.PrimaryKey, O.AutoInc) 
    def street = column[String]("street") 
    def number = column[String]("number") 
    def zipcode = column[String]("zipcode") 
    def city = column[String]("city") 
    def country = column[String]("country") 
    def geoLocationId = column[Int]("geo_location_id", O.Nullable) 

// Foreign keys. 
def geoLocation = foreignKey("fk_geo_location", geoLocationId, GeoLocations)(_.id) 

// Rest of my code. 
... 
} 

dove la mia classe caso è:

case class AddressRow(
    id: Option[Int] = None, 
    street: String, 
    number: String, 
    zipcode: String, 
    city: String, 
    country: String, 
    geoLocationId: Option[Int]) 

Come si nota geolocalizzazione è una chiave esterna opzionale ....

non posso trovare un modo per descrivere questo "Optional" nella mia definizione di chiave esterna.

Ho provato come:

def geoLocation = foreignKey("fk_geo_location", geoLocationId.asColumnOf[Option[Int]], GeoLocations)(_.id) 

ma ricevo:

Causato da: scala.slick.SlickException: Impossibile utilizzare colonna Applicare funzione CAST nel vincolo di chiave esterna (nominato solo colonne sono consentite)

Qualcuno ha un suggerimento?

risposta

3

Non penso che ciò che stai cercando di fare sia ottenibile utilizzando chiavi esterne. Dai un'occhiata a joining e user defined types dai documenti Slick.

Nota l'esempio con la leftJoin:

val explicitLeftOuterJoin = for { 
    (c, s) <- Coffees leftJoin Suppliers on (_.supID === _.id) 
} yield (c.name, s.name.?) 

Quindi, se si voleva interrogare per tutti i tuoi Addresses, che ci si vuole iniziare con qualcosa di simile

val addressGeolocQuery = for { 
    (addr, loc) <- Addresses leftJoin GeoLocations on (_.geoLocationId === _.id) 
} yield addr.id ~ loc.prop1.? ~ loc.prop2.? /*and so on*/ 

È quindi possibile mappare i risultati di tale query in modo che si ottiene un'istanza effettiva Address, completa con un Option[GeoLocation]. Ecco perché ho collegato i "tipi definiti dall'utente" nei documenti ... questa è una novità per me (avevo familiarità con ScalaQuery, che era la precedente incarnazione di Slick), ma sembra abbastanza promettente.

10

provare quanto segue:

def geoLocationId = column[Option[Int]]("geo_location_id") 
//Foreign Key 
def geoLocation = foreignKey("fk_geo_location", geoLocationId, GeoLocations)(_.id.?) 

geoLocationId è ora una colonna di Option[Int] quindi O.Nullable non è più necessario (_.id.?) restituisce il GeoLocation come opzione, o None se fosse nullo.

+0

Ah, funziona. Grazie. – liutao