【问题标题】:Closing sequence of inserts (that return autoinc id) as a single DBIOAction插入的关闭序列(返回 autoinc id)作为单个 DBIOAction
【发布时间】:2017-03-18 00:58:03
【问题描述】:

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

我已经使用 Slick 一个多星期了,我真正喜欢它的是能够以 DBIOAction 的形式关闭操作序列,它可以由我的函数返回,然后可以作为侧面应用到 DB效果。

当我将数据插入单个表时,一切正常。但是,考虑到 ID 是自动递增的,如果必须在我插入的第二行中使用一个插入行的 ID(如任何 1 对多关系),我应该如何处理这种情况?

假设我们有一个 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 自动递增时,这很棘手。 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] = ???

【问题讨论】:

    标签: slick


    【解决方案1】:

    所以我会回答我自己的问题,因为起初有人可能会像我一样觉得它很奇怪。

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

    诀窍在于categoryId 也是一个 DBIOAction,而不是我最初预期的 Int。微不足道,但你去吧。

    【讨论】:

    • 很抱歉迟到了评论,但代码的最终版本是什么?您是否需要在两次调用中破坏 DBIO.seq(...)?
    【解决方案2】:

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

    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))
    

    【讨论】:

      猜你喜欢
      • 2014-03-20
      • 2020-06-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-25
      • 1970-01-01
      • 2017-09-13
      相关资源
      最近更新 更多