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

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

问题描述

我有两个模型(比如供应商咖啡),Coffee模型有对供应商模式的外键引用。在ddl期间,我希望这种关系存在于表格创建中。但是我也希望能够通过Coffee对象来引用供应商对象,比如 coffeeObj.supplier.name 。以下是我的虚拟代码。我正在使用 MappedTable foreignKey TypeMapper

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

object SlickTest {
//供应商
案例类别供应商(id:Option [Int],name:String)
对象供应商扩展表[供应商](供应商){
def id =列[ 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
}

//从供应商到Int的隐式转换
implicit val supTypeMapper = MappedTypeMapMap.base [Supplier,Int](
{s => s.id.get},{id => Suppliers.findOneById(id)})

// Coffee
case class咖啡(名称:Option [String],sup:供应商,价格:Double)
对象Coffees extends表[Coffee](coffee){
def name = column [String] (cof_name,O.PrimaryKey)
def sup = column [Supplier](supplier)
def price = column [Double](price)
def * = name。 ?价格<> (Coffee,Coffee.unapply _)

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

supplier 的定义的最后一行代码失败。任何人都可以点亮任何东西?

解决方案

在Slick中,您不映射到引用其他案例类的案例类。要解决外键,你使用查询,而不是你可以把它放在方法重用。



另见我的文章: https://groups.google.com/d/msg/scalaquery/esFb2DjoHVE/NtMj7BmpE94J



编辑:
不能在coffeeObj中跟随引用,这是一件好事。因为这需要配置一个类似于ORM的加载策略,这会更加复杂,并且会使代码的执行行为变得不那么明显。



延迟加载可能会加载在控制器和供应商coffeeObj看来,这似乎很奇怪,对不对?您可以这样做:

从<$ c中删除 .firstOption.get $ c> findOneById 方法,然后:
$ b

val supplierQuery = Query (供应商).findById(id)
val coffeeQuery = supplierQuery.join(Coffee).on(...)。map(_._ 2)
//这里是你想要的,供应商和相应的咖啡:
val supplierWithCoffee =(supplierQuery.firstOption,coffeeQuery.f irstOption)

把连接放入一个函数来保存锅炉板。


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)
  }
}

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

解决方案

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.

Also see my post at: https://groups.google.com/d/msg/scalaquery/esFb2DjoHVE/NtMj7BmpE94J

EDIT: 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.

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 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.

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

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