如何获取 table = Rep[Option[Long]] 的 max(id) 用于后续插入,而无需在两者之间调用 db.run
How to get max(id) of table = Rep[Option[Long]] for subsequent insert, without calling db.run in between
我有一个 table 的插入,这取决于另一个 table 的最大 ID。
def add(languageCode: String,
typeId: Long,
properties: Seq[Property]): Unit = {
val dbAction = (
for{
nodeId <- (nodes.all returning nodes.all.map(_.id)) += Node(typeId)
language <- (languages.all filter (_.code === languageCode)).result.head
_ <- DBIO.seq(properties.map
{
property =>
val id = property.id
val name = property.key
val value = property.value
if(id == 0) {
val currentPropId: FixedSqlAction[Option[Long], h2Profile.api.NoStream, Effect.Read] = this.properties.all.map(_.id).max.result
val propertyId = (this.properties.all returning this.properties.all.map(_.id)) += Property(language.id.get, currentPropId + 1, name)
nodeProperties.all += NodeProperty(nodeId, 2, value)
} else {
nodeProperties.all += NodeProperty(nodeId, id, value)
}
}: _*)
} yield()).transactionally
db.run(dbAction)
}
如您所见,问题是 currentPropId
是 Rep[Option[Long]]
类型,当然 Property
需要一个合适的 Long
。
对于 languageId,只需在查询 (languages.all filter (_.code === languageCode)).result.head
中添加 result
但是对于 currentPropId
类型仍然是 FixedSqlAction
编辑:
像这样尝试
if(id == 0) {
this.properties.all.map(_.id).max.map {
id =>
val propertyId = (this.properties.all returning this.properties.all.map(_.id)) += Property(language.id.get, id+1, name)
val nodeProperty = nodeProperties.all += NodeProperty(nodeId, 2, value)
propertyId andThen nodeProperty
}
不起作用,因为那不再是 Seq[DBIOAction]
,而是 Seq[Object]
(不是 Any
,而是 Object
)
您不能将提升类型 (Rep[_]) 与标准 Scala 类型混合使用。
您可以映射 SqlAction
以提取所需的类型。
val currentPropId: FixedSqlAction[Option[Long], NoStream, Effect.Read] = ???
currentPropId.flatMap { id: Option[Long] =>
???
}
在你的具体情况下,是这样的:
if(id == 0) {
properties.map(_.id).max.result.flatMap { id: Option[Long] =>
val propertyId = (properties returning properties.map(_.id)) += Property(language.id.get, id.map(_ + 1), name)
val nodeProperty = nodeProperties += NodeProperty(nodeId, 2, value)
propertyId andThen nodeProperty
}
}
...
我有一个 table 的插入,这取决于另一个 table 的最大 ID。
def add(languageCode: String,
typeId: Long,
properties: Seq[Property]): Unit = {
val dbAction = (
for{
nodeId <- (nodes.all returning nodes.all.map(_.id)) += Node(typeId)
language <- (languages.all filter (_.code === languageCode)).result.head
_ <- DBIO.seq(properties.map
{
property =>
val id = property.id
val name = property.key
val value = property.value
if(id == 0) {
val currentPropId: FixedSqlAction[Option[Long], h2Profile.api.NoStream, Effect.Read] = this.properties.all.map(_.id).max.result
val propertyId = (this.properties.all returning this.properties.all.map(_.id)) += Property(language.id.get, currentPropId + 1, name)
nodeProperties.all += NodeProperty(nodeId, 2, value)
} else {
nodeProperties.all += NodeProperty(nodeId, id, value)
}
}: _*)
} yield()).transactionally
db.run(dbAction)
}
如您所见,问题是 currentPropId
是 Rep[Option[Long]]
类型,当然 Property
需要一个合适的 Long
。
对于 languageId,只需在查询 (languages.all filter (_.code === languageCode)).result.head
result
但是对于 currentPropId
类型仍然是 FixedSqlAction
编辑:
像这样尝试
if(id == 0) {
this.properties.all.map(_.id).max.map {
id =>
val propertyId = (this.properties.all returning this.properties.all.map(_.id)) += Property(language.id.get, id+1, name)
val nodeProperty = nodeProperties.all += NodeProperty(nodeId, 2, value)
propertyId andThen nodeProperty
}
不起作用,因为那不再是 Seq[DBIOAction]
,而是 Seq[Object]
(不是 Any
,而是 Object
)
您不能将提升类型 (Rep[_]) 与标准 Scala 类型混合使用。
您可以映射 SqlAction
以提取所需的类型。
val currentPropId: FixedSqlAction[Option[Long], NoStream, Effect.Read] = ???
currentPropId.flatMap { id: Option[Long] =>
???
}
在你的具体情况下,是这样的:
if(id == 0) {
properties.map(_.id).max.result.flatMap { id: Option[Long] =>
val propertyId = (properties returning properties.map(_.id)) += Property(language.id.get, id.map(_ + 1), name)
val nodeProperty = nodeProperties += NodeProperty(nodeId, 2, value)
propertyId andThen nodeProperty
}
}
...