Slick DBIO:master-detail

时间:2015-09-17 07:54:32

标签: slick master-detail slick-3.0

我需要从主 - 细节关系中收集报告数据。这是一个简化的例子:

  case class Person(id: Int, name: String)
  case class Order(id: String, personId: Int, description: String)

  class PersonTable(tag: Tag) extends Table[Person](tag, "person") {
    def id = column[Int]("id")
    def name = column[String]("name")
    override def * = (id, name) <>(Person.tupled, Person.unapply)
  }

  class OrderTable(tag: Tag) extends Table[Order](tag, "order") {
    def id = column[String]("id")
    def personId = column[Int]("personId")
    def description = column[String]("description")
    override def * = (id, personId, description) <>(Order.tupled, Order.unapply)
  }
  val persons = TableQuery[PersonTable]
  val orders = TableQuery[OrderTable]

  case class PersonReport(nameToDescription: Map[String, Seq[String]])

  /** Some complex function that cannot be expressed in SQL and
    * in slick's #join.
    */ 
  def myScalaCondition(person: Person): Boolean =
    person.name.contains("1")
  // Doesn't compile:
  //      val reportDbio1:DBIO[PersonReport] = 
  //        (for{ allPersons <- persons.result
  //              person <- allPersons
  //              if myScalaCondition(person)
  //              descriptions <- orders.
  //                filter(_.personId == person.id).
  //                map(_.description).result
  //            } yield (person.name, descriptions)
  //         ).map(s => PersonReport(s.toMap))
  val reportDbio2: DBIO[PersonReport] =
    persons.result.flatMap {
      allPersons =>
        val dbios = allPersons.
          filter(myScalaCondition).map { person =>
          orders.
            filter(_.personId == person.id).
            map(_.description).result.map { seq => (person.name, seq) }
        }
        DBIO.sequence(dbios)
    }.map(ps => PersonReport(ps.toMap))

它看起来很遥远。当我需要收集3个级别的主细节数据时,它变得难以理解。

有更好的方法吗?

0 个答案:

没有答案