问题
I have the (working) following code:
val actions = (for {
_ <- slickUsers.insertOrUpdate(dbUser)
loginInfo <- loginInfoAction
_ <- slickUserLoginInfos += DBUserLoginInfo(dbUser.userID, loginInfo.id.get)
} yield ()).transactionally
with loginInfoAction being a DBIOAction. I would like to change loginInfoActions to a Seq of DBIOAction and for each of them, execute the same DBUserLoginInfo action afterwards.
I tried this stupidly:
val actions = (for {
_ <- slickUsers.insertOrUpdate(dbUser)
loginInfoAction <- loginInfoActions
loginInfo <- loginInfoAction
_ <- slickUserLoginInfos += DBUserLoginInfo(dbUser.userID, loginInfo.id.get)
} yield ()).transactionally
But it does not work as expected (I would have though loginInfoAction would iterate over the Seq of DBIOAction). I am a newbie in Slick so do not hesitate to point me to the documentation if I missed anything !
回答1:
DBIO.sequence
Use DBIO.sequence
to convert List[DBIO[_]]
to DBIO[List[_]]
and use for-comprehension.
DBIO.sequence
will convert the sequence of DBIO's into DBIO[Seq[_]]
.
For example let say we have a function getUser
def getUser(userId: Long): DBIO[User]
def getAllUsers(userIds: List[Long]): DB[List[User]] = {
DBIO.sequence(userIds.map(getUser))
}
DBIO.Sequence
converts List[DBIO[_]]
to DBIO[List[_]]
Now your code becomes
val actions = (for {
_ <- slickUsers.insertOrUpdate(dbUser)
loginInfoActionList <- DBIO.sequence(loginInfoActions)
_ <- DBIO.sequence { loginInfoActionList.map { loginInfo =>
slickUserLoginInfos += DBUserLoginInfo(dbUser.userID, loginInfo.id.get) }
}
} yield ()).transactionally
来源:https://stackoverflow.com/questions/40758492/slick-combine-actions-with-a-seq-of-dbioaction