【问题标题】:Entity Framework stored procedure Insert custom sequential number实体框架存储过程插入自定义序号
【发布时间】:2012-05-15 20:47:27
【问题描述】:

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

我在 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 and type=@type

INSERT INTO TABLE(位置、类型、id ......)值(@location、@type、@nextnumber、......)

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

选择 @nextNumber 作为 [NextNumber]

【问题讨论】:

  • 尝试将伪造的否定键分配给新实体。像 -1、-2 这样 EF 可以将它们分开。

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


【解决方案1】:

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

【讨论】:

  • 嗨,它是这样设置的,ID/Location/type 是关键
  • ID是不是也无意间在数据库中自己设置为主键了?
  • 不,唯一的PK是3的复合。
【解决方案2】:

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

【讨论】:

  • 你能解释一下你的评论吗?我添加了一个我正在使用的 sp 的示例。
  • 通常有一列纯粹是行的唯一标识符。 (遗憾的是,“唯一标识符”一词被重载,通常表示“Guid”。我没有使用该定义,而只是“唯一”。)通常此列被命名为 Id 或只是 Id。它出现在您的使用中-case,Id列代表“位置/类型的序列”,没有“唯一”列。
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-02
    • 1970-01-01
    • 1970-01-01
    • 2013-03-19
    相关资源
    最近更新 更多