Scala 光滑和嵌套的情况下,一个不去?

Scala 光滑和嵌套的情况下,一个不去?,scala,playframework,playframework-2.0,slick,slick-2.0,Scala,Playframework,Playframework 2.0,Slick,Slick 2.0,我正在使用slick(和play框架)在现有数据库的基础上构建一个应用程序。我无法更改数据库结构 我的数据库有以下两个表: 会议: id(主键) 名字 主席id(FK至个人id) 房东id(FK至个人id) 人: id(主键) 名字 姓 我想这样定义我的案例类: case class Meeting ( id: Int, name: String, chairman: Person, houseman: Person ) case class Person (

我正在使用slick(和play框架)在现有数据库的基础上构建一个应用程序。我无法更改数据库结构

我的数据库有以下两个表:

会议:

  • id(主键)
  • 名字
  • 主席id(FK至个人id)
  • 房东id(FK至个人id)
人:

  • id(主键)
  • 名字
我想这样定义我的案例类:

case class Meeting (
  id: Int,
  name: String,
  chairman: Person,
  houseman: Person
) 

case class Person (
   id: Int,
   firstName: String,
   lastName: String
)
val thisMeeting = meetings.filter(_.name === "thisMeeting").join(persons).on((m, p) => m.housemanId === p.id || m.chairmanId === p.id).list()
但是从最简单的文档来看,我似乎必须将ID保存在case类中,而不是使用“Person”。对吗

最好的方法是什么?对不起,这个相对开放的问题,对scala来说很新,很流畅,很好玩

谢谢


Ed

您有外键,它们不会转换为case类,而是转换为id:

case class Meeting (
  id: Int,
  name: String,
  chairmanId: Int,
  housemanId: Int) 

 case class Person (
  id: Int,
  firstName: String,
  lastName: String)
模式应该是这样的:

 case class Meeting (
                   id: Int,
                   name: String,
                   chairmanId: Int,
                   housemanId: Int)

 case class Person (
                  id: Int,
                  firstName: String,
                  lastName: String)


class Meetings(tag: Tag) extends Table[Meeting](tag, "meeting") {
  def * = (id, name, chairmanId, housemanId) <>(Meeting.tupled, Meeting.unapply)

  def ? = (id.?, name, chairmanId, housemanId).shaped.<>({
    r => import r._
      _1.map(_ => Meeting.tupled((_1.get, _2, _3, _4)))
  }, (_: Any) => throw new Exception("Inserting into ? projection not supported."))

  val id: Column[Int] = column[Int]("id", O.AutoInc, O.PrimaryKey)
  val name: Column[String] = column[String]("name")
  val chairmanId: Column[Int] = column[Int]("chairmanId")
  val housemanId: Column[Int] = column[Int]("housemanId")

  lazy val meetingChairmanFk =
    foreignKey("meeting_chairman_fk", chairmanId, persons)(r => r.id, onUpdate = ForeignKeyAction.Restrict, onDelete = ForeignKeyAction.Cascade)


  lazy val meetingHousemanFk =
    foreignKey("meeting_houseman_fk", housemanId, persons)(r => r.id, onUpdate = ForeignKeyAction.Restrict, onDelete = ForeignKeyAction.Cascade)


}

lazy val meetings = new TableQuery(tag => new Meetings(tag))

class Persons(tag: Tag) extends Table[Person](tag, "person") {
  def * = (id, firstName, lastName) <>(Person.tupled, Person.unapply)

  def ? = (id.?, firstName, lastName).shaped.<>({
    r => import r._
      _1.map(_ => Person.tupled((_1.get, _2, _3)))
  }, (_: Any) => throw new Exception("Inserting into ? projection not supported."))

  val id: Column[Int] = column[Int]("id", O.AutoInc, O.PrimaryKey)
  val firstName: Column[String] = column[String]("firstname")
  val lastName: Column[String] = column[String]("lastname")


}

lazy val persons = new TableQuery(tag => new Persons(tag))
或用于理解(我个人认为更清晰):

val thatMeething=(用于{

m感谢Ende,我有一个非常类似的模型,但我不确定加载链接对象的方法应该是什么。因此,如果我加载一个会议,我希望相关的两个人也被加载。我必须通过连接查询将它们作为元组加载吗?我在回答中添加了一个示例。是的,edward,你需要像SQL中那样的连接查询。不同的是你可以把它放到一个函数中,然后和其他查询组合起来。所以基本上,这个查询片段就是你的关系映射,因为你只需要指定一次,然后在需要的地方使用它。cvogt,我可以看到你已经多次给出这个答案了,但是我仍然不相信它在开发中是有意义的r的观点。我们不应该围绕持久性层来构建数据。Dbauman我完全同意你的观点。我只是把这看作是框架的一个限制。正因为如此,我希望远离slick。
val thatMeething = (for {
  m <- meetings
  p <- persons if (p.id === m.chairmanId || p.id === m.housemanId) && m.name === "thatMeeting"
} yield m.id).run