我正在使用实体框架来填充网格控件。有时当我进行更新时,我得到以下错误:
存储更新、插入或删除语句影响了意外的行数(0)。实体可能在加载实体后已被修改或删除。刷新ObjectStateManager条目。
我不知道怎么复制这个。但这可能和我更新的时间间隔有关系。有人见过这个吗,或者有人知道错误消息指的是什么吗?
编辑:不幸的是,我不再有自由重现我在这里遇到的问题,因为我离开了这个项目,不记得我最终是否找到了解决方案,是否有其他开发人员修复了它,或者是否我绕过了它。因此我不能接受任何回答。
我正在使用实体框架来填充网格控件。有时当我进行更新时,我得到以下错误:
存储更新、插入或删除语句影响了意外的行数(0)。实体可能在加载实体后已被修改或删除。刷新ObjectStateManager条目。
我不知道怎么复制这个。但这可能和我更新的时间间隔有关系。有人见过这个吗,或者有人知道错误消息指的是什么吗?
编辑:不幸的是,我不再有自由重现我在这里遇到的问题,因为我离开了这个项目,不记得我最终是否找到了解决方案,是否有其他开发人员修复了它,或者是否我绕过了它。因此我不能接受任何回答。
当前回答
行[DatabaseGenerated(System.ComponentModel.DataAnnotations.DatabaseGeneratedOption.None)]在我的例子中发挥了作用:
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public int? SomeNumber { get; set; }
其他回答
我也有同样的问题,我发现这是由RowVersion为null引起的。 检查Id和RowVersion是否为空。
有关更多信息,请参阅本教程
http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/handling-concurrency-with-the-entity-framework-in-an-asp-net-mvc-application
我今天遇到了一个类似的问题,我将在这里记录它,因为它不完全是乐观并发错误。
我正在将一个旧系统转换为一个新的数据库,它有几千个实体,我必须把它们脚本转移到新系统。然而,为了帮助理智,我选择保持原始的唯一id,所以是注入到新对象,然后尝试保存它。
我遇到的问题是,我使用MVC脚手架来创建基本存储库,他们在他们的UpdateOrInsert方法中有一个模式,基本上是在添加新实体或将其状态更改为modified之前检查是否设置了Key属性。
因为设置了Guid,所以它试图修改数据库中实际上不存在的行。
我希望这能帮助到其他人!
我也有同样的问题。但这是我自己的失误。实际上,我是保存一个对象,而不是添加它。这就是矛盾所在。
当公认的答案说“它不会最终覆盖应用程序不知道已经发生的更改”时,我很怀疑,因为我的对象是新创建的。但后来发现,有一个INSTEAD OF UPDATE, INSERT- TRIGGER附加到表中,它正在更新同一表的计算列。
一旦我将其更改为AFTER INSERT, UPDATE,它就可以正常工作了。
这是乐观并发特性的副作用。
不是100%确定如何在实体框架中打开/关闭它,但基本上它告诉你的是,当你从数据库中获取数据时,当你保存你的更改时,其他人已经更改了数据(这意味着当你保存它时,0行实际上得到了更新)。在SQL术语中,它们的更新查询的where子句包含行中每个字段的原始值,如果0行受到影响,它就知道出错了。
它背后的思想是,你最终不会覆盖你的应用程序不知道发生了什么变化——它基本上是。net在所有更新中附带的一个小安全措施。
如果它是一致的,那么它很可能发生在您自己的逻辑中(例如:您实际上是在选择和更新之间的另一个方法中自己更新数据),但它可能只是两个应用程序之间的竞争条件。