Scala Slick 3.1.x如何实现多对多连接?

Scala Slick 3.1.x如何实现多对多连接?,scala,slick,Scala,Slick,在UserDao中,我试图定义一个方法,给定一个用户将获得分配给它的所有安全角色。这是一个多对多关系,这里是伪数据库设计(): 因此,我尝试如下定义我的getRoles函数: def getRoles(user: UserRow) : Future[List[SecurityRoleRow]] = { val action = for { role <- SecurityRole join UserSecurityRole on (_.id === _.securityRoleId

UserDao
中,我试图定义一个方法,给定一个用户将获得分配给它的所有安全角色。这是一个多对多关系,这里是伪数据库设计():

因此,我尝试如下定义我的
getRoles
函数:

def getRoles(user: UserRow) : Future[List[SecurityRoleRow]] = {
  val action = for {
  role <- SecurityRole join UserSecurityRole on (_.id === _.securityRoleId) 
            join User on (_.userId === _.id)
  } yield role
  db.run(action)
}
def getRoles(user: UserRow) : Future[List[SecurityRoleRow]] = {
  val action = for {
    role <- SecurityRole join (UserSecurityRole join User on (_.userId === _.id)) on (_.id === _.securityRoleId)
  } yield role
  db.run(action)
}
就这样。然后,如果我想将此SQL平滑化到我的
UserDao
中,我可以:

def getRoles(user: UserRow) : Future[List[SecurityRoleRow]] = {
  val action = sql"""SELECT t1.* " +
                    "FROM SecurityRole t1, " + 
                         "UserSecurityRole t2, " +
                    "WHERE t1.id = t2.securityRoleId " +
                      "AND ${user.id} = t2.userId""".as[SecurityRoleRow]
    db.run(action)
}
您基本上是对的(嗯,有点像,它们并没有被删除,而是元组得到了扩展)。与此相反:

def getRoles(user: UserRow) : Future[List[SecurityRoleRow]] = {
  val action = for {
  role <- SecurityRole join UserSecurityRole on (_.id === _.securityRoleId) 
            join User on (_.userId === _.id)
  } yield role
  db.run(action)
}
每个新连接都会添加新的嵌套元组。请看我在这里的演示文稿中的这张幻灯片(我用模式匹配来解构每种类型的元组,但都是一样的):(特别是,请看下一张幻灯片,它通过使用外键使其更加整洁;在您的情况下,这将是一个完美的解决方案)

编辑:

即使不定义外键(我认为您应该这样做),也可以将版本更改为一元形式,从而避免所有元组嵌套:

val action = (for {
  role <- SecurityRole 
  userRole <- UserSecurityRole if role.id === userRole.securityRoleId 
  user <- User if userRole.userId === user.id
} yield role).result

db.run(action)
val action=(用于{

role@giovanni azua基本上我建议你看一下演示文稿和相关的回购协议。这是对Slick 3.x基础知识的一种快速介绍。在参考资料部分,你还可以链接到Dave Gurnell主持的非常好的研讨会录音()感谢您的详尽回答!使用pure slick与SQL版本的性能比较如何?我将找到如何获取生成的SQL以获得想法。非常感谢!您已经在我链接的幻灯片上生成了SQL。此外,要轻松查看生成的内容,只需将这组记录器添加到
logback.xml
def getRoles(user: UserRow) : Future[List[SecurityRoleRow]] = {
  val action = for {
  role <- SecurityRole join UserSecurityRole on (_.id === _.securityRoleId) 
            join User on (_.userId === _.id)
  } yield role
  db.run(action)
}
def getRoles(user: UserRow) : Future[List[SecurityRoleRow]] = {
  val action = (for {
  role <- SecurityRole join UserSecurityRole on (_.id === _.securityRoleId) 
            join User on (_._2.userId === _.id) // here is the change!!
  } yield role).result
  db.run(action)
}
val action = (for {
  role <- SecurityRole 
  userRole <- UserSecurityRole if role.id === userRole.securityRoleId 
  user <- User if userRole.userId === user.id
} yield role).result

db.run(action)