Scala 光滑和嵌套的情况下,一个不去?
我正在使用slick(和play框架)在现有数据库的基础上构建一个应用程序。我无法更改数据库结构 我的数据库有以下两个表: 会议: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 (
- 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