Slick-使用foreignKey约束并直接作为列访问引用的对象 [英] Slick- use foreignKey constraint and access referenced object directly as column

查看:34
本文介绍了Slick-使用foreignKey约束并直接作为列访问引用的对象的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have two models (say, Supplier and Coffee) and Coffee model has foreign key reference to Supplier model. During ddl, I want this relationship to exist in table creation. But I also want to be able to refer the Supplier object through Coffee object like coffeeObj.supplier.name. Below is my dummy code. I am using MappedTable, foreignKey and TypeMapper.

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 定义的最后一行失败.有人能解释一下吗?

The code is failing at the last line for the definition of supplier. Could anyone shed any light?

推荐答案

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

In Slick you don't map to case classes that reference other case classes. To resolve foreign keys you use queries instead, which you can put into methods for re-usability.

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

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

You can't follow a reference in coffeeObj and that is a good thing. Because that would require configuring a loading strategy like in ORMs, which would be more complicated and would make the execution behavior of your code less obvious.

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

Lazy loading would probably load the coffeeObj in the controller and the supplier in the view, which seems odd, right? You can do this:

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

Remove .firstOption.get from your findOneById method and then:

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)

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

Put the join into a function to save boiler plate.

这篇关于Slick-使用foreignKey约束并直接作为列访问引用的对象的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆