2013-07-24 12 views
9

Sto lottando con le tabelle di incorporamento e mappatura sollevate di Slick. L'API mi sembra strana, forse solo perché è strutturata in un modo che non mi è familiare.Come utilizzare le tabelle mappate di Slick con chiavi esterne?

Voglio creare un Task/Todo-List. Esistono due entità:

  • Attività: Ogni attività ha un riferimento facoltativo all'attività successiva. In questo modo viene creata una lista collegata. L'intenzione è che l'utente possa ordinare le attività in base alla sua priorità. Questo ordine è rappresentato dai riferimenti dall'attività all'attività.
  • TaskList: Rappresenta una TaskList con un'etichetta e un riferimento alla prima operazione della lista.

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


Ora ho provato a scrivere un oggetto di accesso ai dati (DAO) per queste due entità.

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

Sfortunatamente non viene compilato. I problemi sono nella proiezione * di entrambi i tavoli allo nextTask rispettivamente firstTask.

  • 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]]

ho cercato di risolvere questo con il seguente TypeMapper ma che non compila, troppo.

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.

domanda principale: come utilizzare di Slick sollevato embedding e mappati tabelle nel modo giusto? Come posso farlo funzionare?

Grazie in anticipo.

risposta

6

La risposta breve è: utilizzare gli ID invece di riferimenti a oggetti e utilizzare le query Slick agli ID dereference. È possibile inserire le query in metodi da riutilizzare.

che renderebbe le vostre classi case simile a questa:

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

pubblicherò un articolo su questo argomento ad un certo punto e link qui.

+0

Ciao cvogt, questa limitazione è ancora presente per Slick 2.0? Hai un riferimento su come dovrebbe essere ordinata questa situazione? Grazie! –

+0

Ciao. Hai pubblicato il tuo articolo? – n1r3

+0

No, ma è ancora sulla mia lista e probabilmente accadrà qualche tempo fino all'estate. Lo annuncerò nella mailing list di Slick. – cvogt

Problemi correlati