【问题标题】:Slick MSSQL inserting object with auto increment具有自动增量的 Slick MSSQL 插入对象
【发布时间】:2013-08-05 15:44:59
【问题描述】:

我最近不得不将一个项目从 MySQL 转移到 MSSQL。我在我的表的 id 列上使用IDENTITY(1,1) 以匹配 MySQL 的自动增量功能。

当我尝试插入一个对象时,我收到了这个错误:

[SQLServerException: Cannot insert explicit value for identity column in table 'categories' when IDENTITY_INSERT is set to OFF.]

现在经过一些研究,我发现这是因为我试图在我的表上插入我的 id(0) 的值。所以例如我有一个对象类别

case class Category(
  id: Long = 0L,
  name: String
)
object Category extends Table[Category]("categories"){

  def name = column[String]("name", O.NotNull)
  def id = column[Long]("id", O.PrimaryKey, O.AutoInc)

  def * = id ~ name <> (Category.apply _, Category.unapply _)

  def add(model:Category) = withSession{ implicit session =>
    Category.insert(model)
  }
  def remove(id:Long) = withSession{implicit session =>
    try{Some(Query(Category).filter(_.id === id).delete)}
    catch{case _ => None}
  }
}

有没有办法将我的对象插入数据库并忽略 0L 而 MSSQL 不会抛出 SQLException? MySQL 会忽略 id 的值并像没有收到 id 一样进行增量。 我真的不想用除了 id 之外的所有东西创建一个新的案例类。

【问题讨论】:

    标签: sql-server scala slick


    【解决方案1】:

    尝试像这样重新定义您的 add 方法,看看它是否适合您:

    def add(model:Category) =  withSession{ implicit session =>
      Category.name.insert(model.name)
    }
    

    如果您有更多列,那么您可以将 forInsert 投影添加到您的 Category 表类中,该投影指定除 id 之外的所有字段,但既然您没有,这应该可以代替。

    编辑

    现在,如果您的表格对象上确实有 2 个以上的字段,那么您可以执行类似的操作,这在 Lifted Embedding 文档here 中有描述:

    case class Category(
      id: Long = 0L,
      name: String,
      foo:String
    )
    object Category extends Table[Category]("categories"){
      def id = column[Long]("id", O.PrimaryKey, O.AutoInc)
      def name = column[String]("name", O.NotNull)
      def foo = column[String]("foo", O.NotNull)
    
      def * = id ~ name ~ foo <> (Category.apply _, Category.unapply _)
    
      def forInsert = name ~ foo <> (t => Category(0L, t._1, t._2), {(c:Category) => Some(c.name, c.foo)})
    
      def add(model:Category) =  withSession{ implicit session =>
        Category.forInsert insert model
      }
      def remove(id:Long) = withSession{implicit session =>
        try{Some(Query(Category).filter(_.id === id).delete)}
        catch{case _ => None}
      }
    
      def withSession(f: Session => Unit){
    
      }
    }
    

    【讨论】:

    • 我的大多数对象至少有 6 个字段,那么有没有一种方法可以在不重写所有字段的情况下进行此投影?重写除一个字段之外的所有字段似乎非常不雅。因为如果我想添加一个字段,它必须在多个地方。
    • @kingdamian42,我添加了更多关于两个以上字段的代码。我希望这就是你要找的。​​span>
    • 是的,谢谢,这就是我想出的。我只是希望有一种方法可以让我不必做太多的硬编码。因为现在如果我要添加一些东西我必须将它添加到案例类中,在对象中添加一个def,添加到*,添加到forInsert,当然还要添加到数据库中。要添加的内容很多,您会认为可以将其合并到一个位置。不过,我想现在必须这样做,谢谢。
    猜你喜欢
    • 2016-07-27
    • 1970-01-01
    • 2018-02-17
    • 2014-08-03
    • 2016-04-06
    • 2015-10-05
    • 2012-05-29
    • 2015-10-14
    • 1970-01-01
    相关资源
    最近更新 更多