实体框架6:存储更新,插入或删除语句影响了意外的行数(0)

时间:2014-06-12 17:26:42

标签: sql entity-framework

我希望有人可以帮助我在实体框架中进行更新时找出以下错误的原因。

  

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

根据我的阅读,这意味着数据在获取和保存之间已经发生了变化,但在我的情况下并非如此。 (在本地运行应用程序的单个开发人员。在尝试保存之前,我也查看了数据库中的数据,这与我执行获取时完全相同。还可以在命令中重现此数据。)

我不确定这是否相关,但它似乎是唯一与其他正在运作的实体不同的因素。我有一个实体代表一个带有复合键的表。我正在更新的值是构成组合键的值之一。目前表中只有一条记录,所以我知道没有主要密钥违规的事情发生。

有谁知道我可以采取哪些步骤来找出实际问题是什么?

谢谢

4 个答案:

答案 0 :(得分:1)

如果您在插入的表上没有触发器,则会导致此错误。您必须在插入触发器后重写触发器,或者在触发器结束时选择新生成的ID。也许更新有类似的问题。查看查询实体框架生成 - 它可以帮助您查看正在进行的操作。

修改

要查看生成的查询,请设置日志记录:

public class CustomContext : DbContext
{
    public CustomContext()
        : base("name=CustomString")
    {
        // configure writing queries to console
        Database.Log = Console.Write;
    }

    // other context stuf ...
}

或使用一些探查器(对于sql server express,您可以使用http://expressprofiler.codeplex.com/)。

答案 1 :(得分:0)

问题在于您调用方法_dataContext.SaveChanges();,但数据中没有任何变化。要避免此错误,请尝试以下操作:

public void EditCustomer(Customer customer)
    {
        _dataContext.Customer.Attach(customer);
        var entry = _dataContext.Entry(customer);

        if(entry.Property(e => e.DeviceId).CurrentValue != entry.Property(e => e.DeviceId).OriginalValue)
        {
            entry.Property(e => e.DeviceId).IsModified = true;
        }

        if(entry.Property(e => e.Name).CurrentValue != entry.Property(e => e.Name).OriginalValue)
        {
            entry.Property(e => e.Name).IsModified = true;
        }


        if(entry.Property(e => e.DeviceId).IsModified || entry.Property(e => e.Name).IsModified)
        {
            _dataContext.SaveChanges();
        }            
    }

我希望这会对你有所帮助。

@DonPablone

答案 2 :(得分:0)

我遇到了这样的错误消息,我的环境如下,首先是SQL Server 2016和ef6数据库,问题是数据库开发人员未在我的表的ID列中定义标识种子列m将数据插入其中,当然,当我更新表设计时,问题就解决了,所以我分享这种经验,以防万一有人遇到相同的问题。

答案 3 :(得分:0)

如果有机会,尝试使用Attach()然后使用SaveChanges()组合来更新记录时,我们也会遇到相同的问题?这可能会帮助...

我正在使用SQLite DB及其EF提供程序(相同的代码在SQLServer DB中可以正常工作)。

我发现,当您的数据库列在SQLite中具有GUID(或UniqueIdentity)并且您的模型为nvarchar时,SQLIte EF默认将其视为Binary(即,byte [])。因此,当SQLite EF提供程序尝试将GUID转换为模型(在我的情况下为字符串)时,它将失败,因为它将转换为byte []。解决方法是通过定义“ BinaryGUID = false;”来告诉SQLite EF将GUID视为TEXT(因此转换为字符串,而不是byte [])。在连接字符串(或元数据,如果您首先使用数据库)中,如下所示:

  <connectionStrings>
    <add name="Entities" connectionString="metadata=res://savetyping...=System.Data.SQLite.EF6;provider connection string=&quot;data source=C:\...\db.sqlite3;Version=3;BinaryGUID=false;App=EntityFramework&quot;" providerName="System.Data.EntityClient" />
  </connectionStrings>

链接到对我有用的解决方案: How does the SQLite Entity Framework 6 provider handle Guids?