我正在使用实体框架来填充网格控件。有时当我进行更新时,我得到以下错误:
存储更新、插入或删除语句影响了意外的行数(0)。实体可能在加载实体后已被修改或删除。刷新ObjectStateManager条目。
我不知道怎么复制这个。但这可能和我更新的时间间隔有关系。有人见过这个吗,或者有人知道错误消息指的是什么吗?
编辑:不幸的是,我不再有自由重现我在这里遇到的问题,因为我离开了这个项目,不记得我最终是否找到了解决方案,是否有其他开发人员修复了它,或者是否我绕过了它。因此我不能接受任何回答。
我正在使用实体框架来填充网格控件。有时当我进行更新时,我得到以下错误:
存储更新、插入或删除语句影响了意外的行数(0)。实体可能在加载实体后已被修改或删除。刷新ObjectStateManager条目。
我不知道怎么复制这个。但这可能和我更新的时间间隔有关系。有人见过这个吗,或者有人知道错误消息指的是什么吗?
编辑:不幸的是,我不再有自由重现我在这里遇到的问题,因为我离开了这个项目,不记得我最终是否找到了解决方案,是否有其他开发人员修复了它,或者是否我绕过了它。因此我不能接受任何回答。
当前回答
检查你是否忘记了GridView中的“DataKeyNames”属性。 当在GridView中修改数据时,它是必须的
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.datakeynames.aspx
其他回答
我也遇到了同样的问题。
我使用EF 6,代码优先+迁移。 问题是我们的DBA在抛出错误的表上创建了一个约束。
这是乐观并发特性的副作用。
不是100%确定如何在实体框架中打开/关闭它,但基本上它告诉你的是,当你从数据库中获取数据时,当你保存你的更改时,其他人已经更改了数据(这意味着当你保存它时,0行实际上得到了更新)。在SQL术语中,它们的更新查询的where子句包含行中每个字段的原始值,如果0行受到影响,它就知道出错了。
它背后的思想是,你最终不会覆盖你的应用程序不知道发生了什么变化——它基本上是。net在所有更新中附带的一个小安全措施。
如果它是一致的,那么它很可能发生在您自己的逻辑中(例如:您实际上是在选择和更新之间的另一个方法中自己更新数据),但它可能只是两个应用程序之间的竞争条件。
在同一个上下文中使用SaveChanges(false)和后来的SaveChanges()时得到此错误,在一个工作单元中,从两个表中删除多行(在上下文中)(SaveChanges(false)在其中一个删除中。然后在调用函数中,SaveChanges()被调用为....解决方案是删除不必要的SaveChanges(false)。
您需要显式地包含主键的BoundField。如果你不想让用户看到主键,你必须通过css隐藏它:
<asp:BoundField DataField="Id_primary_key" ItemStyle-CssClass="hidden"
HeaderStyle-CssClass="hidden" />
其中'hidden'是css中的一个类,它的显示设置为'none'。
我遇到这种情况是因为datetime和datetime2之间不匹配。奇怪的是,在测试人员发现问题之前,它工作得很好。我的Code First模型包括一个DateTime作为主键的一部分:
[Key, Column(Order = 2)]
public DateTime PurchasedDate { get; set; } = (DateTime)SqlDateTime.MinValue;
生成的列是一个datetime列。当调用SaveChanges时,EF生成了以下SQL:
-- Region Parameters
DECLARE @0 Int = 2
DECLARE @1 Int = 25
DECLARE @2 Int = 141051
DECLARE @3 DateTime2 = '2017-07-27 15:16:09.2630000' --(will not equal a datetime value)
-- EndRegion
UPDATE [dbo].[OrganizationSurvey]
SET [OrganizationSurveyStatusId] = @0
WHERE ((([SurveyID] = @1) AND ([OrganizationID] = @2)) AND ([PurchasedDate] = @3))
因为它试图将datetime列与datetime2值匹配,所以没有返回任何结果。我能想到的唯一解决方案是将列更改为datetime2:
[Key, Column(Order = 2, TypeName = "DateTime2")]
public DateTime PurchasedDate { get; set; } = (DateTime)SqlDateTime.MinValue;