实体框架存储过程插入自定义序列号

时间:2012-05-15 20:47:27

标签: c# .net entity-framework-4

请耐心等待我的解释。

我在EF4中使用映射存储过程设置了一个用于插入数据的表。

示例:

    id | location | type
    1  |     10   |  15
    5  |     10   |  16

SP的作用是在另一个表中检查下一个按位置和类型对应的ID。

所以在这个例子中,下一个id是

  • 2表示位置10和类型15
  • 6 for location 10 type 16

这可以通过在EF中映射结果列来实现。

除非两个不同的键具有相同的序列号示例,否则它可以正常工作:

    id | location | type
    1  |     10   |  11
    1  |     10   |  10

编辑:当我同时创建两个新行时会发生此错误。

它们的下一个值是2,数据保存到数据库但应用程序失败并显示以下消息:

  

已成功提交对数据库的更改,但发生了错误   在更新对象上下文时。 ObjectContext可能位于   不一致的状态   内部异常消息:
  AcceptChanges无法继续,因为对象的键值与另一个键值冲突   ObjectStateManager中的对象   在调用AcceptChanges之前,请确保键值是唯一的。

有什么建议吗?

编辑 存储过程示例

  

声明@nextNumber int

     

SELECT @nextNumber = value + 1 FROM SEQUENTIAL_TABLE WHERE location = @location and type = @ type

     

INSERT INTO TABLE(location,type,id,......)VALUES(@location,@ type,@ nextnumber,.......)

     

更新SEQUENTIAL_TABLE SET值= @nextNumber WHERE location = @location并输入= @ type

     

将@nextNumber选为[NextNumber]

3 个答案:

答案 0 :(得分:1)

不了解更多设计;你可以修改你的表,使ID不是主键,而是使用ID / Location / Type作为复合键。

答案 1 :(得分:0)

听起来你错误地使用id列而不仅仅意味着“自动递增int”。

答案 2 :(得分:0)

“假负数”是一个很好的技巧,并且在DataSet / TableAdapter时代非常好用。如果这不起作用,也许这是一个竞争条件,你需要将细节放在一个事务中,这样任何其他线程/行都不能获得下一个id,直到你完成递增并插入你的。

相关问题