8

我有两个模型(例如,SupplierCoffee),并且 Coffee 模型具有对 Supplier 模型的外键引用。在 ddl 期间,我希望这种关系存在于表创建中。但我也希望能够通过 Coffee 对象引用 Supplier 对象,例如coffeeObj.supplier.name. 下面是我的虚拟代码。我正在使用MappedTableforeignKeyTypeMapper

import scala.slick.driver.H2Driver.simple._
import Database.threadLocalSession

object SlickTest {
  // Supplier
  case class Supplier(id: Option[Int], name: String)
  object Suppliers extends Table[Supplier]("supplier") {
    def id = column[Int]("id", O.PrimaryKey, O.AutoInc)
    def name = column[String]("name")
    def * = id.? ~ name <> (Supplier, Supplier.unapply _)
    def findOneById(id: Int): Supplier = 
      this.map { e => e }.where(r => r.id === id).firstOption.get
  }

  // Implicit Conversion from Supplier to Int
  implicit val supTypeMapper = MappedTypeMapper.base[Supplier, Int](
    { s => s.id.get }, { id => Suppliers.findOneById(id) })

  // Coffee
  case class Coffee(name: Option[String], sup: Supplier, price: Double)
  object Coffees extends Table[Coffee]("coffee") {
    def name = column[String]("cof_name", O.PrimaryKey)
    def sup = column[Supplier]("supplier")
    def price = column[Double]("price")
    def * = name.? ~ sup ~ price <> (Coffee, Coffee.unapply _)

    def supplier = foreignKey("SUP_FK", sup, Suppliers)(_.id)
  }
}

代码在定义的最后一行失败supplier。有人能解释一下吗?

4

1 回答 1

8

在 Slick 中,您不会映射到引用其他案例类的案例类。要解析外键,您可以改用查询,您可以将其放入方法中以实现可重用性。

另请参阅我的帖子:https ://groups.google.com/d/msg/scalaquery/esFb2DjoHVE/NtMj7BmpE94J

编辑: 您不能遵循 coffeeObj 中的参考,这是一件好事。因为这需要像在 ORM 中那样配置加载策略,这会更复杂,并且会使代码的执行行为不那么明显。

延迟加载可能会在控制器中加载coffeeObj,在视图中加载供应商,这看起来很奇怪,对吧?你可以这样做:

.firstOption.get从您的方法中删除findOneById,然后:

val supplierQuery = Query(Suppliers).findById(id)
val coffeeQuery = supplierQuery.join(Coffee).on(...).map(_._2)
// here is what you want, a supplier and the corresponding coffee:
val supplierWithCoffee = (supplierQuery.firstOption,coffeeQuery.f​irstOption)

将连接放入函数中以保存样板。

于 2013-10-17T13:49:10.937 回答