我正在使用实体框架来填充网格控件。有时当我进行更新时,我得到以下错误:

存储更新、插入或删除语句影响了意外的行数(0)。实体可能在加载实体后已被修改或删除。刷新ObjectStateManager条目。

我不知道怎么复制这个。但这可能和我更新的时间间隔有关系。有人见过这个吗,或者有人知道错误消息指的是什么吗?

编辑:不幸的是,我不再有自由重现我在这里遇到的问题,因为我离开了这个项目,不记得我最终是否找到了解决方案,是否有其他开发人员修复了它,或者是否我绕过了它。因此我不能接受任何回答。


当前回答

最近,我正在尝试将EF5升级为EF6样本项目。示例项目的表格有十进制(5,2)类型的列。数据库迁移成功完成。但是,初始数据种子产生了异常。

模型:

    public partial class Weather
    {
    ...
    public decimal TMax {get;set;}
    public decimal TMin {get;set;}
    ...
    }

配置错误:

public partial class WeatherMap : EntityTypeConfiguration<Weather>
{

    public WeatherMap()
    {
        ...
        this.Property(t => t.TMax).HasColumnName("TMax");
        this.Property(t => t.TMin).HasColumnName("TMin");
        ...
    }
}

数据:

    internal static Weather[] data = new Weather[365]
    {
      new Weather() {...,TMax = 3.30M,TMin = -12.00M,...},
      new Weather() {...,TMax = 5.20M,TMin = -10.00M,...},
      new Weather() {...,TMax = 3.20M,TMin = -8.00M,...},
      new Weather() {...,TMax = 11.00M,TMin = -7.00M,...},
      new Weather() {...,TMax = 9.00M,TMin = 0.00M,...},
    };

我发现了问题,播种数据有精度值,但配置没有精度和比例参数。在样本表中用十进制(10,0)定义的TMax和TMin字段。

正确配置:

public partial class WeatherMap : EntityTypeConfiguration<Weather>
{

    public WeatherMap()
    {
        ...
        this.Property(t => t.TMax).HasPrecision(5,2).HasColumnName("TMax");
        this.Property(t => t.TMin).HasPrecision(5,2).HasColumnName("TMin");
        ...
    }
}

我的示例项目运行在:MySql 5.6.14, Devart.Data。MySql, MVC4, .Net 4.5.1, EF6.01

致以最亲切的问候。

其他回答

我将抛出这个,以防有人在并行循环中工作时遇到这个问题:

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();
    }
}

不确定这是否是“最佳实践”,但它通过让每个并行操作使用自己的上下文来解决我的问题。

我在使用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> 

我今天遇到了一个类似的问题,我将在这里记录它,因为它不完全是乐观并发错误。

我正在将一个旧系统转换为一个新的数据库,它有几千个实体,我必须把它们脚本转移到新系统。然而,为了帮助理智,我选择保持原始的唯一id,所以是注入到新对象,然后尝试保存它。

我遇到的问题是,我使用MVC脚手架来创建基本存储库,他们在他们的UpdateOrInsert方法中有一个模式,基本上是在添加新实体或将其状态更改为modified之前检查是否设置了Key属性。

因为设置了Guid,所以它试图修改数据库中实际上不存在的行。

我希望这能帮助到其他人!

当公认的答案说“它不会最终覆盖应用程序不知道已经发生的更改”时,我很怀疑,因为我的对象是新创建的。但后来发现,有一个INSTEAD OF UPDATE, INSERT- TRIGGER附加到表中,它正在更新同一表的计算列。

一旦我将其更改为AFTER INSERT, UPDATE,它就可以正常工作了。

我遇到了这个问题,这是由于实体的ID(键)字段没有设置造成的。因此,当上下文去保存数据时,它找不到ID = 0。请确保在更新语句中放置断点,并验证实体的ID是否已设置。

来自Paul Bellora的评论

我也遇到过同样的问题,因为忘记包含隐藏ID 在.cshtml编辑页面中输入