在使用LINQ到SQL连接(针对SQL Server Compact Edition)更新了几个属性之后,对DataContext执行SubmitChanges时,我得到一个"未找到或更改的行"ChangeConflictException.

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"时,没有关于失败原因的其他信息.我还确认了这个异常get抛出时,数据库中正好有一条记录(我试图更新的记录)

奇怪的是,我在另一段代码中有一个非常相似的UPDATE语句,它生成以下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之后,似乎要检测冲突,最好判断所有字段,但我认为这将是相当低效的.这是不是一直都是这样?是否有只判断主键的设置?

在过go 的两个小时里,我一直在努力解决这个问题,所以如果有任何帮助,我将不胜感激.

推荐答案

这很难听,但很简单:

判断O/R-Designer中所有字段的数据类型是否与SQL表中的数据类型匹配. Double check for nullable!列在O/R-Designer和SQL中都应该为空,或者在两者中都不能为空.

例如,在数据库中,NVARCHAR列"title"被标记为可为NULL,并包含NULL值.即使列在O/R映射中被标记为不可为null,LINQ也会成功加载它并将列字符串设置为null.

  • 现在你换个地方打电话
  • LINQ将生成SQL查询 包含"WHERE[title]is null",以确保标题未被其他人更改.
  • LINQ查找
  • LINQ将发现[title]不可为空.
  • 由于[title]不可为空
  • 所以,优化查询,林克

如果字段的数据类型与SQL中的数据类型不匹配,或者字段丢失,则会出现相同的症状,因为LINQ无法确保自读取数据后SQL数据没有更改.

.net相关问答推荐

从Couchbase删除_txn文档的推荐方法?""

仅在有换行符时捕获分隔符之间的所有文本

如何知道变量是否只是指向另一个对象的pointer或者它是否可以独立存在

每当属性值发生变化时引发事件?

为什么 .net 对字符串使用 UTF16 编码,但默认使用 UTF-8 来保存文件?

在 C# 中将字符串转换为 colored颜色

mstest.exe 在哪里?

使用 Windows 服务和 C# 检测 USB 驱动器插入和移除

app.config 文件和 XYZ.settings 文件有什么区别?

如何明智地使用 StringBuilder?

Int 到字节数组

C# 的 Actors 有什么好的实现吗?

找不到 Assert.Fail 和 Assert.Pass 或等效项

新的 netstandardapp 和 netcoreapp TFM 有什么区别?

如何在可取消的异步/等待中处理 TransactionScope?

析构函数、dispose 和 finalize 方法的区别

加载程序集、查找类和调用 Run() 方法的正确方法

如何在 WPF 中的 Xaml 文件中添加注释?

将月份 int 转换为月份名称

使用 C# vs F# 或 F# vs C# 有什么好处?