LINQ to SQLite无法更新:“存储更新,插入或删除语句影响了意外的行数”

时间:2015-05-30 01:37:44

标签: c# .net linq sqlite system.data.sqlite

使用System.Data.SQLite和LINQ to Entities,我无法进行简单的更新。

此代码

using (Entities context = new Entities()) {
    var Obj = context.MyTable.Where(m => m.Title.StartsWith("Alaska")).FirstOrDefault();
    Obj.Artist = "A";
    context.SaveChanges();
}

引发此异常

A first chance exception of type 'System.Data.Entity.Infrastructure.DbUpdateConcurrencyException' occurred in EntityFramework.dll

Additional information: Store update, insert, or delete statement affected an unexpected number of rows (0). Entities may have been modified or deleted since entities were loaded. Refresh ObjectStateManager entries.

我该如何解决这个问题?

我正处于一个孤立的测试项目中,所以周围没有任何其他事情发生。

2 个答案:

答案 0 :(得分:1)

数据库是来自SQL Server数据库的自动转换,结果是SQLite不支持UNIQUEIDENTIFIER数据类型,但该表仍然将列和主键定义为UNIQUEIDENTIFIER。每当我更新具有UNIQUEIDENTIFIER键的表时,我都会收到此错误。使用INT键更新表时,它没问题。

解决方案是将这些列的数据类型更改为TEXT。然后在.NET映射类中,数据类型从Guid更改为String,因此我必须相应地调整代码,但现在它可以正常工作。

答案 1 :(得分:0)

当尝试使用SaveChanges()时,我们可能会遇到相同的问题。就我而言,我使用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?