2013-07-24 8 views
9

Ich kämpfe mit Slicks angehobenen Einbetten und gemappten Tabellen. Die API fühlt sich komisch an, vielleicht nur weil sie auf eine mir unbekannte Art und Weise strukturiert ist.Wie verwendet Slick die zugeordneten Tabellen mit Fremdschlüsseln?

Ich möchte eine Task/Todo-Liste erstellen. Es gibt zwei Entitäten:

  • Aufgabe: Jede Aufgabe hat einen optionalen Verweis auf die nächste Aufgabe. Auf diese Weise wird eine verkettete Liste erstellt. Die Absicht ist, dass der Benutzer die Aufgaben nach seiner Priorität ordnen kann. Diese Reihenfolge wird durch die Referenzen von Aufgabe zu Aufgabe dargestellt.
  • TaskList: Repräsentiert eine TaskList mit einer Bezeichnung und einem Verweis auf die erste Aufgabe der Liste.

    case class Task(id: Option[Long], title: String, nextTask: Option[Task])
    case class TaskList(label: String, firstTask: Option[Task])


Jetzt habe ich versucht, ein Datenzugriffsobjekt (DAO) für diese beiden Entitäten zu schreiben.

import scala.slick.driver.H2Driver.simple._ 
import slick.lifted.MappedTypeMapper 

implicit val session: Session = Database.threadLocalSession 
val queryById = Tasks.createFinderBy(t => t.id) 

def task(id: Long): Option[Task] = queryById(id).firstOption 

    private object Tasks extends Table[Task]("TASKS") { 
    def id = column[Long]("ID", O.PrimaryKey, O.AutoInc) 
    def title = column[String]("TITLE") 
    def nextTaskId = column[Option[Long]]("NEXT_TASK_ID") 
    def nextTask = foreignKey("NEXT_TASK_FK", nextTaskId, Tasks)(_.id) 
    def * = id ~ title ~ nextTask <> (Task, Task.unapply _) 
    } 

    private object TaskLists extends Table[TaskList]("TASKLISTS") { 
    def label = column[String]("LABEL", O.PrimaryKey) 
    def firstTaskId = column[Option[Long]]("FIRST_TASK_ID") 
    def firstTask = foreignKey("FIRST_TASK_FK", firstTaskId, Tasks)(_.id) 
    def * = label ~ firstTask <> (Task, Task.unapply _) 
    } 

Leider kompiliert es nicht. Die Probleme sind in der * Projektion beider Tabellen bei nextTask bzw. firstTask zu finden.

  • could not find implicit value for evidence parameter of type scala.slick.lifted.TypeMapper[scala.slick.lifted.ForeignKeyQuery[SlickTaskRepository.this.Tasks.type,justf0rfun.bookmark.model.Task]]
  • could not find implicit value for evidence parameter of type scala.slick.lifted.TypeMapper[scala.slick.lifted.ForeignKeyQuery[SlickTaskRepository.this.Tasks.type,justf0rfun.bookmark.model.Task]]

Ich habe versucht, dass mit dem folgenden TypeMapper zu lösen, aber das auch nicht kompilieren.

implicit val taskMapper = MappedTypeMapper.base[Option[Long], Option[Task]](
    option => option match { 
     case Some(id) => task(id) 
     case _ => None 
    }, 
    option => option match { 
     case Some(task) => task.id 
     case _ => None 
    }) 
  • could not find implicit value for parameter tm: scala.slick.lifted.TypeMapper[Option[justf0rfun.bookmark.model.Task]]
  • not enough arguments for method base: (implicit tm: scala.slick.lifted.TypeMapper[Option[justf0rfun.bookmark.model.Task]])scala.slick.lifted.BaseTypeMapper[Option[Long]]. Unspecified value parameter tm.

Hauptfrage: Wie Slicks verwenden angehoben Einbettung und kartiert Tabellen der richtige Weg? Wie bekomme ich das zur Arbeit?

Vielen Dank im Voraus.

Antwort

6

Die kurze Antwort lautet: Verwenden Sie IDs anstelle von Objektreferenzen, und verwenden Sie Slick-Abfragen, um die IDs zu dereferenzieren. Sie können die Abfragen in Methoden zur Wiederverwendung ablegen.

, dass Ihre Fall Klassen machen würde wie folgt aussehen:

case class Task(id: Option[Long], title: String, nextTaskId: Option[Long]) 
case class TaskList(label: String, firstTaskId: Option[Long]) 

Ich werde einen Artikel über dieses Thema zu einem bestimmten Zeitpunkt veröffentlichen und hier verlinkt.

+0

Hi cvogt, ist diese Einschränkung für Slick 2.0 noch vorhanden? Haben Sie einen Hinweis, wie diese Situation sortiert werden soll? Vielen Dank! –

+0

Hallo. Hast du deinen Artikel veröffentlicht? – n1r3

+0

Nein, aber es ist immer noch auf meiner Liste und wird wahrscheinlich noch einige Zeit bis zum Sommer passieren. Ich werde es auf der Slick-Mailing-Liste bekannt geben. – cvogt

Verwandte Themen