我正在使用实体框架来填充网格控件。有时当我进行更新时,我得到以下错误:
存储更新、插入或删除语句影响了意外的行数(0)。实体可能在加载实体后已被修改或删除。刷新ObjectStateManager条目。
我不知道怎么复制这个。但这可能和我更新的时间间隔有关系。有人见过这个吗,或者有人知道错误消息指的是什么吗?
编辑:不幸的是,我不再有自由重现我在这里遇到的问题,因为我离开了这个项目,不记得我最终是否找到了解决方案,是否有其他开发人员修复了它,或者是否我绕过了它。因此我不能接受任何回答。
我正在使用实体框架来填充网格控件。有时当我进行更新时,我得到以下错误:
存储更新、插入或删除语句影响了意外的行数(0)。实体可能在加载实体后已被修改或删除。刷新ObjectStateManager条目。
我不知道怎么复制这个。但这可能和我更新的时间间隔有关系。有人见过这个吗,或者有人知道错误消息指的是什么吗?
编辑:不幸的是,我不再有自由重现我在这里遇到的问题,因为我离开了这个项目,不记得我最终是否找到了解决方案,是否有其他开发人员修复了它,或者是否我绕过了它。因此我不能接受任何回答。
当前回答
我还遇到了这个错误。问题原来是由我试图保存到的桌子上的触发器引起的。触发器使用了'INSTEAD OF INSERT',这意味着0行被插入到该表,因此出现了错误。幸运的是,在可能的情况下,触发器功能是不正确的,但我猜它可能是一个有效的操作,应该以某种方式在代码中处理。希望有一天这能帮助到别人。
其他回答
public void Save(object entity)
{
using (var transaction = Connection.BeginTransaction())
{
try
{
SaveChanges();
transaction.Commit();
}
catch (OptimisticConcurrencyException)
{
if (ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Deleted || ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Modified)
this.Refresh(RefreshMode.StoreWins, entity);
else if (ObjectStateManager.GetObjectStateEntry(entity).State == EntityState.Added)
Detach(entity);
AcceptAllChanges();
transaction.Commit();
}
}
}
我在使用Telerik的RadGrid时遇到了这个问题。我将主键设置为只读的绑定列。如果列是display="false",它会工作得很好,但readonly="true"导致了问题。我通过将绑定列display=false并添加一个单独的模板列来解决这个问题
<telerik:GridBoundColumn HeaderText="Shouldnt see" Display="false"
UniqueName="Id" DataField="Id">
</telerik:GridBoundColumn>
<telerik:GridTemplateColumn HeaderText="Id" UniqueName="IdDisplay">
<ItemTemplate>
<asp:Label ID="IDLabel" runat="server"
Text='<%# Eval("Id") %>'></asp:Label>
</ItemTemplate>
</telerik:GridTemplateColumn>
检查你是否忘记了GridView中的“DataKeyNames”属性。 当在GridView中修改数据时,它是必须的
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.datakeynames.aspx
我也有同样的问题,我发现这是由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
我将抛出这个,以防有人在并行循环中工作时遇到这个问题:
Parallel.ForEach(query, deet =>
{
MyContext ctx = new MyContext();
//do some stuff with this to identify something
if(something)
{
//Do stuff
ctx.MyObjects.Add(myObject);
ctx.SaveChanges() //this is where my error was being thrown
}
else
{
//same stuff, just an update rather than add
}
}
我把它改成如下:
Parallel.ForEach(query, deet =>
{
MyContext ctxCheck = new MyContext();
//do some stuff with this to identify something
if(something)
{
MyContext ctxAdd = new MyContext();
//Do stuff
ctxAdd .MyObjects.Add(myObject);
ctxAdd .SaveChanges() //this is where my error was being thrown
}
else
{
MyContext ctxUpdate = new MyContext();
//same stuff, just an update rather than add
ctxUpdate.SaveChanges();
}
}
不确定这是否是“最佳实践”,但它通过让每个并行操作使用自己的上下文来解决我的问题。