2013-02-26 5 views
6

mit einer Klasse und Tabellendefinition aussehen wie diese Aktualisierung:Ärger einen Datensatz mit Slick

case class Group(
    id: Long = -1, 
    id_parent: Long = -1, 
    label: String = "", 
    description: String = "") 

    object Groups extends Table[Group]("GROUPS") { 
    def id = column[Long]("ID", O.PrimaryKey, O.AutoInc) 
    def id_parent = column[Long]("ID_PARENT") 
    def label = column[String]("LABEL") 
    def description = column[String]("DESC") 
    def * = id ~ id_parent ~ label ~ design <> (Group, Group.unapply _) 
    def autoInc = id_parent ~ label ~ design returning id into { 
     case ((_, _, _), id) => id 
    } 
    } 

einen Datensatz zu aktualisieren, kann ich dies tun:

def updateGroup(id: Long) = Groups.where(_.id === id) 

    def updateGroup(g: Group)(implicit session: Session) = updateGroup(g.id).update(g) 

Aber ich kann nicht Updates Verwendung für Ausdrücke zu arbeiten:

val findGById = for { 
    id <- Parameters[Long] 
    g <- Groups; if g.id === id 
    } yield g 

    def updateGroupX(g: Group)(implicit session: Session) = findGById(g.id).update(g) 
    ----------------------------------------------------------------------------^ 
Error: value update is not a member of scala.slick.jdbc.MutatingUnitInvoker[com.exp.Group] 

fehlt mir natürlich etwas in the documentation.

Antwort

7

Die Methode update wird vom Typ UpdateInvoker geliefert. Eine Instanz dieses Typs kann implizit von einem Query mit den Methoden productQueryToUpdateInvoker und/oder tableQueryToUpdateInvoker (in der BasicProfile gefunden) erstellt werden, wenn sie im Anwendungsbereich sind.

Nun ist der Typ Ihrer findById Methode kein Query sondern ein BasicQueryTemplate[Long, Group]. Betrachtet man die Dokumente, kann ich keinen Weg finden von einem BasicQueryTemplate (der ein Subtyp von StatementInvoker ist) zu einem UpdateInvoker, weder implizit noch explizit. Wenn ich darüber nachdenke, ergibt das einen Sinn für mich, da ich eine Abfragevorlage (Invoker) als etwas verstehe, das schon früh vor der Parametrisierung aus einem abstrakten Syntaxbaum (Query) zu einer vorbereiteten Anweisung "kompiliert" wurde, während ein update invoker kann nur aus einem abstrakten Syntaxbaum, dh einem Query Objekt, erstellt werden, da es die Abfrage analysieren und ihre Parameter/Spalten extrahieren muss. So scheint es zur Zeit zumindest zu funktionieren.

Mit dem im Verstand, eine mögliche Lösung entfaltet:

def findGById(id: Long) = for { 
    g <- Groups; if g.id === id 
} yield g 

def updateGroupX(g: Group)(implicit session: Session) = findGById(g.id).update(g) 

Wo findById(id: Long) den Typen hat Query[Groups, Group] die von productQueryToUpdateInvoker zu einem UpdateInvoker[Group] auf der umgewandelt wird die update Methoden schließlich aufgerufen werden können.

Hoffe das half.

+0

Eine gute Erklärung, warum es nicht funktioniert, aber es scheint mir, dass es eine [Einschränkung des Slick-Framework] ist (https://github.com/slick/slick/issues/102). Die Tatsache, dass BasicQueryTemplate nicht so reich ist wie Query, scheint es unmöglich zu machen, Abfragen mit Parametern und sortBy oder groupBy zwischenzuspeichern. –