光滑构建过滤条件

时间:2014-07-16 16:43:51

标签: scala slick slick-2.0

我认为下面的代码主要说明一切,但这里有一个简短的解释。

我有一个需要添加到查询条件的ID列表。我可以轻松地“和”查询条件(请参阅下面的val incorrect),但我很难找到一个“或”条件的好方法。

id列表不是静态的,我只是把一些放在那里作为例子。如果可能的话,我想知道如何使用for comprehension,而不使用for comprehension。

此外,如果要运行代码,您应该能够在repl中删除此代码并添加一些导入。

object Tbl1Table {

  case class Tbl1(id:Int, gid: Int, item: Int)

  class Tbl1Table(tag:Tag) extends Table[Tbl1](tag, "TBL1") {
    val id = column[Int]("id")
    val gid = column[Int]("gid")
    val item = column[Int]("item")

    def * = (id, gid, item) <> (Tbl1.tupled, Tbl1.unapply)
  }
  lazy val theTable = new TableQuery(tag => new Tbl1Table(tag))

  val ids = List((204, 11), (204, 12), (204, 13), (205, 19))

  val query = for {
    x <- theTable
  } yield x

  println(s"select is ${query.selectStatement}")
  //prints: select is select x2."id", x2."gid", x2."item" from "TBL1" x2

  val idsGrp = ids.groupBy(_._1)
  val incorrect = idsGrp.foldLeft(query)((b, a) =>
    b.filter(r => (r.gid is a._1) && (r.item inSet(a._2.map(_._2))))
  )

  println(s"select is ${incorrect.selectStatement}")
  //prints: select is select x2."id", x2."gid", x2."item" from "TBL1" x2
  //        where ((x2."gid" = 205) and (x2."item" in (19))) and
  //              ((x2."gid" = 204) and (x2."item" in (11, 12, 13)))

  //but want to "or" everything, ie:
  //prints: select is select x2."id", x2."gid", x2."item" from "TBL1" x2
  //        where ((x2."gid" = 205) and (x2."item" in (19))) or
  //              ((x2."gid" = 204) and (x2."item" in (11, 12, 13)))
}

1 个答案:

答案 0 :(得分:0)

这似乎工作正常:

import scala.slick.driver.PostgresDriver.simple._

case class Tbl1Row(id:Int, gid: Int, item: Int)

class Tbl1Table(tag:Tag) extends Table[Tbl1Row](tag, "TBL1") {
  val id = column[Int]("id")
  val gid = column[Int]("gid")
  val item = column[Int]("item")

  def * = (id, gid, item) <> (Tbl1Row.tupled, Tbl1Row.unapply)
}

lazy val theTable = new TableQuery(tag => new Tbl1Table(tag))

val ids = List((204, 11), (204, 12), (204, 13), (205, 19))
val idsGrp = ids.groupBy(_._1)
val correct = theTable.filter(r => idsGrp.map(t => (r.gid is t._1) && (r.item inSet(t._2.map(_._2)))).reduce(_ || _))
println(s"select is ${correct.selectStatement}")

输出

select is select s16."id", s16."gid", s16."item" from "TBL1" s16 where ((s16."gid" = 205) and (s16."item" in (19))) or ((s16."gid" = 204) and (s16."item" in (11, 12, 13)))