.net - 如何解决 SQL Server Compact Edition 数据库上 LINQ to SQL 中的 "Row not found or changed"异常?

标签 .net linq linq-to-sql

在使用 LINQ to SQL 连接(针对 SQL Server Compact Edition)更新几个属性后对 DataContext 执行 SubmitChanges 时,我收到“未找到或更改行”的消息。更改冲突异常。

var ctx = new Data.MobileServerDataDataContext(Common.DatabasePath);
var deviceSessionRecord = ctx.Sessions.First(sess => sess.SessionRecId == args.DeviceSessionId);

deviceSessionRecord.IsActive = false;
deviceSessionRecord.Disconnected = DateTime.Now;

ctx.SubmitChanges();

查询生成以下 SQL:

UPDATE [Sessions]
SET [Is_Active] = @p0, [Disconnected] = @p1
WHERE 0 = 1
-- @p0: Input Boolean (Size = 0; Prec = 0; Scale = 0) [False]
-- @p1: Input DateTime (Size = 0; Prec = 0; Scale = 0) [9/4/2008 5:12:02 PM]
-- Context: SqlProvider(SqlCE) Model: AttributedMetaModel Build: 3.5.21022.8

明显的问题是WHERE 0=1,加载记录后,我确认“deviceSessionRecord”中的所有属性都正确包含主键。此外,当捕获“ChangeConflictException”时,没有关于失败原因的附加信息。我还确认数据库中只有一条记录(我正在尝试更新的记录)引发此异常

奇怪的是,我在不同的代码部分有一个非常相似的更新语句,它生成以下 SQL 并且确实更新了我的 SQL Server Compact Edition 数据库。

UPDATE [Sessions]
SET [Is_Active] = @p4, [Disconnected] = @p5
WHERE ([Session_RecId] = @p0) AND ([App_RecId] = @p1) AND ([Is_Active] = 1) AND ([Established] = @p2) AND ([Disconnected] IS NULL) AND ([Member_Id] IS NULL) AND ([Company_Id] IS NULL) AND ([Site] IS NULL) AND (NOT ([Is_Device] = 1)) AND ([Machine_Name] = @p3)
-- @p0: Input Guid (Size = 0; Prec = 0; Scale = 0) [0fbbee53-cf4c-4643-9045-e0a284ad131b]
-- @p1: Input Guid (Size = 0; Prec = 0; Scale = 0) [7a174954-dd18-406e-833d-8da650207d3d]
-- @p2: Input DateTime (Size = 0; Prec = 0; Scale = 0) [9/4/2008 5:20:50 PM]
-- @p3: Input String (Size = 0; Prec = 0; Scale = 0) [CWMOBILEDEV]
-- @p4: Input Boolean (Size = 0; Prec = 0; Scale = 0) [False]
-- @p5: Input DateTime (Size = 0; Prec = 0; Scale = 0) [9/4/2008 5:20:52 PM]
-- Context: SqlProvider(SqlCE) Model: AttributedMetaModel Build: 3.5.21022.8

我已确认已在数据库架构和生成 LINQ 类的 DBML 中标识了正确的主字段值。

我想这几乎是一个由两部分组成的问题:

  1. 为什么会抛出异常?
  2. 查看第二组生成的 SQL 后,似乎为了检测冲突,检查所有字段会很好,但我认为这会相当低效。这总是这样吗?有没有设置只检查主键?

过去两个小时我一直在努力解决这个问题,因此我们将不胜感激。

最佳答案

这很令人讨厌,但很简单:

检查 O/R-Designer 中所有字段的数据类型是否与 SQL 表中的数据类型匹配。 双重检查是否可以为空!列应该在 O/R-Designer 和 SQL 中都可以为空,或者在两者中都不能为空。

例如,NVARCHAR 列“title”在数据库中被标记为 NULLable,并且包含值 NULL。即使该列在 O/R 映射中被标记为 NOT NULLable,LINQ 也会成功加载它并将列字符串设置为 null。

  • 现在你改变一些东西并打电话 提交更改()。
  • LINQ 将生成 SQL 查询 包含“WHERE [title] IS NULL”,以确保标题未被其他人更改。
  • LINQ 查找以下属性 [标题] 在映射中。
  • LINQ 将发现 [title] NOT NULLable。
  • 由于 [title] 不可为 NULL,因此 逻辑它永远不可能是NULL!
  • 所以,优化查询,LINQ 将其替换为“其中 0 = 1”, SQL 相当于“从不”。

当字段的数据类型与 SQL 中的数据类型不匹配,或者字段缺失时,也会出现相同的症状,因为 LINQ 将无法确保 SQL 数据在读取数据后没有发生更改。

关于.net - 如何解决 SQL Server Compact Edition 数据库上 LINQ to SQL 中的 "Row not found or changed"异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45045/

相关文章:

sql - 我将如何在 Linq 中执行此 SQL?

linq-to-sql - Windows 8的Metro风格应用程序中是否可以使用LINQ-to-SQL?

c# - 我的 .NET 应用程序何时/如何使用其 App.Config 文件?

c# - 任务继续未安排在线程池线程上

c# - 使用 LINQ C# 递归获取所有子级

database - 将接口(interface)而不是类映射到数据库表

c# - 我可以在 .net 4 中部署我的 ASP.NET MVC 4 应用程序吗

.net - 自 2012 年 6 月升级 SDK 1.7 以来,Azure 部署不断回收

c# - 使用 Linq 将项目移动到列表底部

c# - 在 EF 4.1 中加载所有导航属性及其子属性的最佳方法是什么