0

请耐心等待我的解释很长。

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

例子 :

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

SP 所做的是在另一个表中检查按位置和类型对应的下一个 id。

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

  • 2 用于位置 10 和类型 15
  • 6 用于位置 10 类型 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 和 type=@type

插入表(位置,类型,id,......)值(@location,@type,@nextnumber,......)

UPDATE SEQUENTIAL_TABLE SET value = @nextNumber WHERE location = @location and type=@type

选择 @nextNumber 作为 [NextNumber]

4

3 回答 3

1

在不了解设计的情况下;您可以修改您的表,使 ID 不是主键,而是使用 ID/Location/Type 集作为复合键。

于 2012-05-15T22:01:01.393 回答
0

听起来您误用了 id 列,而不仅仅是表示“自动递增 int”。

于 2012-05-15T20:55:40.940 回答
0

“假负数”是一个很好的技巧,在 DataSet / TableAdapter 时代工作得非常好。如果这不起作用,也许这是一个竞争条件,您需要将详细信息放在事务中,以便在您完成递增和插入您的之前,没有其他线程/行可以获取下一个 id。

于 2012-05-23T06:04:21.877 回答