2013-03-12 4 views
6

ich eine Tabelle wie folgt aus:Wie definiert man einen optionalen Fremdschlüssel 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. 
... 
} 

wo mein Fall Klasse:

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

Wie Sie die Entfernung zu kennen ist ein optionales Fremdschlüssel bemerken ....

kann ich nicht finde eine Möglichkeit, dieses "Optional" in meiner Fremdschlüsseldefinition zu beschreiben.

Ich habe wie versucht:

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

aber ich erhalten:

Verursacht durch: scala.slick.SlickException: Spalte kann nicht Funktion Cast in Fremdschlüssel verwenden Nehmen (nur benannt Spalten sind zulässig)

Hat jemand einen Vorschlag?

Antwort

3

Ich glaube nicht, dass das, was Sie zu tun versuchen, mit fremden Schlüsseln erreichbar ist. Schauen Sie sich joining und user defined types aus der Slick-Dokumentation an.

Hinweis das Beispiel mit dem leftJoin:

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

Also, wenn Sie für alle Ihre Addresses abfragen wollte, würde man mit so etwas wie

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

starten wollen Sie könnten dann map die Ergebnisse dieser Abfrage, so dass Sie eine tatsächliche Address Instanz erhalten, komplett mit einem Option[GeoLocation]. Deshalb habe ich die "benutzerdefinierten Typen" in den Dokumenten verlinkt ... das ist ein neues Feature für mich (ich kannte ScalaQuery, was Slicks frühere Inkarnation war), aber es sieht ziemlich vielversprechend aus.

10

Versuchen Sie Folgendes:

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

geoLocationId ist jetzt eine Spalte von Option[Int] daher O.Nullable nicht mehr benötigt wird (_.id.?) kehrt die GeoLocation als Option oder None wenn es null war.

+0

Ah, es funktioniert. Vielen Dank. – liutao