关闭插入序列(返回autoinc id)作为单个DBIOAction

时间:2015-07-13 09:53:39

标签: slick

TL; DR:我想创建一个纯函数,它将返回在单个DBIOAction对象内关闭的一系列插入操作(例如def foo():DBIOAction)。当ID不是自动递增时,这是微不足道的,当ID由DB自动递增时,对我来说很难。

我现在已经使用Slick超过一周了,我真正喜欢它的是能够将操作序列作为DBIOAction关闭,可以由我的函数返回,之后可以应用于DB作为DB副作用。

当我将数据插入单个表时,这一切都很好。但是,如果在插入的第二行中必须使用一个插入行的ID(如任何1-many关系),我应该如何处理情况,因为ID是自动递增的?

想象一下,我们有CATEGORIES table列:id, name, parent_id,其中parent_id为NULL或指向表格中的其他行。

如果ID没有自动递增,这是微不足道的:

def insert(cId: Int, cName: String, subcId: Int, subcName: String) = DBIO.seq( categories +=(subcId, subcName, None), categories +=(cId, cName, Some(subcId)) )

但是当ID ARE自动增加时,这很棘手。 As stated in the documentation,我需要将returning结合使用投影到需要返回的列,例如:

val categoryId = (categories returning categories.map(_.id)) += (0, name, None)

现在我可以在插入第二行时使用返回的ID。真棒。但是,我如何关闭数据库操作的序列,因为我返回了ID,但不是动作本身?

def insert(cName: String, subcName: String): DBIOAction[Int, Stream, Write] = ???

2 个答案:

答案 0 :(得分:1)

所以我会回答我自己的问题,因为有人可能会在我开始时发现它很奇怪。

val categoryId = (categories returning categories.map(_.id)) += (0, name, None)

诀窍是categoryId也是 DBIOAction ,而不是我原先预期的Int。琐碎,但你去了。

答案 1 :(得分:0)

我就是这样做的(我在我的一个项目中做过类似的事情):

def insert(cName: String, subcName: String) = {
  for {
    id <- (categories returning categories.map(_.id)) += (subcName, None)
    _ <- categories +=(cName, Some(id))
  } yield ()

然后我会调用函数:

db.run(insert(categoryName, subCategoryName))