【问题标题】:How to join two tables and map the result to a case class in slick如何连接两个表并将结果映射到光滑的案例类
【发布时间】:2016-09-04 12:11:56
【问题描述】:

我正在一个使用 scala play 2 框架的项目中工作,我使用 slick 作为 FRM 和 postgres 数据库。

在我的项目中,客户是一个实体。所以我也创建了一个客户表和客户案例类和对象。另一个实体是帐户。所以我也创建了一个帐户表和帐户案例类和对象。代码如下

case class Customer(id: Option[Int],
            status: String,
            balance: Double,
            payable: Double,
            created: Option[Instant],
            updated: Option[Instant]) extends GenericEntity {
def this(status: String,
   balance: Double,
   payable: Double) = this(None, status, balance, payable, None, None)
}
class CustomerTable(tag: Tag) extends GenericTable[Customer](tag, "customer"){
   override def id = column[Option[Int]]("id")
   def status = column[String]("status")
   def balance = column[Double]("balance")
   def payable = column[Double]("payable")
   def account = foreignKey("fk_customer_account", id, Accounts.table)(_.id,    onUpdate = ForeignKeyAction.Restrict, onDelete = ForeignKeyAction.Cascade)

def * = (id, status, balance, payable, created, updated) <> ((Customer.apply _).tupled, Customer.unapply)
}
object Customers extends GenericService[Customer, CustomerTable] {
   override val table = TableQuery[CustomerTable]
   val accountTable = TableQuery[AccountTable]
   override def copyEntityFields(entity: Customer, id: Option[Int],
   created: Option[Instant], updated: Option[Instant]): Customer = {
      entity.copy(id = id, created = created, updated = updated)
   }
}

现在我想加入客户表和帐户表并将结果映射到名为 CustomerWithAccount 的案例类 我试过下面的代码

case class CustomerDetail(id: Option[Int],
                      status: String,
                      name: String)
object Customers extends GenericService[Customer, CustomerTable] {
   override val table = TableQuery[CustomerTable]
   val accountTable = TableQuery[AccountTable]
   def getAllCustomersWithAccount = db.run(table.join(accountTable).on(_.id === _.id).map { row =>
   //for (row1 <- row) {
     for {
       id <- row._1.id
       status <- row._1.status.toString()
       name <- row._2.name.toString()
     } yield CustomerDetail(id = id, status = status, name = name)
   //}
   }.result)
   override def copyEntityFields(entity: Customer, id: Option[Int], created:Option[Instant], updated: Option[Instant]): Customer = {
    entity.copy(id = id, created = created, updated = updated)
  }
}

但这不起作用。 请帮帮我。

【问题讨论】:

  • 您能否详细说明什么不起作用?代码没有编译,还是抛出了运行时异常?
  • 查看slick.lightbend.com/doc/3.0.0/…(适用于 slick 3.0.0)
  • 如果有人可以为使用 HList 的较大的“非元组”案例类提供解决方案,那就加分!

标签: scala playframework slick


【解决方案1】:

你可以试试这个查询

db.run((table.join(accountTable).on(_.id === _.id)
  .map{
    case (t,a) => ((t.id, t.status, a.name) <> (CustomerDetail.tupled, CustomerDetail.unapply _))
  }).result)

【讨论】:

    【解决方案2】:

    您可以使用 3 个案例类来执行此操作,每个表 1 个,然后 1 个用于连接结果。

    db.run((customerTable.join(accountTable).on(_.id === _.id)
      .map{
         case (c,a) => CustomerWithAccount(status = c.status, created = 
                        c.created, account=a, ...)
       }
    

    【讨论】:

    • 抱歉,安德鲁,这似乎不起作用,至少在 Scala 2.13 和 Slick 3.3.3 上。它抱怨列的类型和它的 Rep[] 版本之间的类型不匹配。
    猜你喜欢
    • 2015-12-04
    • 2016-01-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多