我能做些什么来解决"未找到行或更改"例外的LINQ to SQL在SQL Server Compact Edition数据库?我能、做些什么、未找到、数据库

2023-09-02 01:53:05 作者:ザ溥德噫戀ぎ

在更新一些属性与LINQ到SQL连接(针对SQL Server精简版),我得到一个后执行的SubmitChanges到DataContext未找到行或更改。 ChangeConflictException。

When executing SubmitChanges to the DataContext after updating a couple properties with a LINQ to SQL connection (against SQL Server Compact Edition) I get a "Row not found or changed." 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语句:

The query generates the following 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

最明显的问题是,在,其中0 = 1 ,装载的记录之后,我已经证实,在deviceSessionRecord所有属性都是正确的,包括主键。也赶上了ChangeConflictException时,有一个关于为什么没有任何其他信息。我也证实了此异常得到的与数据库中的一个记录(记录我试图更新)抛出

The obvious problem is the WHERE 0=1, After the record was loaded, I've confirmed that all the properties in the "deviceSessionRecord" are correct to include the primary key. Also when catching the "ChangeConflictException" there is no additional information about why this failed. I've also confirmed that this exception get's thrown with exactly one record in the database (the record I'm attempting to update)

有什么奇怪的是,我在code不同的部分非常相似更新语句,并生成以下SQL和确实更新我的SQL Server Compact Edition数据库。

What's strange is that I have a very similar update statement in a different section of code and it generates the following SQL and does indeed update my SQL Server Compact Edition database.

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被鉴定

I have confirmed that the proper primary fields values have been identified in both the Database Schema and the DBML that generates the LINQ classes.

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

I guess this is almost a two part question:

为什么抛出异常? 回顾了第二组生成的SQL后,好像检测到冲突,将是很好的检查各个领域,但我想这将是非常低效的。这是本永远的工作方式?有没有只检查主键的设置?

我一直在争取这个在过去的二小时,任何帮助,将AP preciated。

I've been fighting with this for the past two hours so any help would be appreciated.

凯文·...

推荐答案

那是肮脏的,但简单的:

Thats nasty, but simple:

检查在O / R-设计各领域的数据类型匹配的数据类型,在你的SQL表。 仔细检查可能为空! A柱应该是可为空的同时在O / R-Designer和SQL,或者不同时为空。

Check if the data types for all fields in the O/R-Designer match the data types in your SQL table. Double check for nullable! A column should be either nullable in both the O/R-Designer and SQL, or not nullable in both.

例如,一个nvarchar列标题被标记为可为空的数据库,并包含NULL值。尽管列标记为不可为空在你的O / R-Mapping功能,LINQ将成功地加载,并设置列字符串为空。

For example, a NVARCHAR column "title" is marked as NULLable in your database, and contains the value NULL. Even though the column is marked as NOT NULLable in your O/R-Mapping, LINQ will load it successfully and set the column-String to null.

现在,你想改变什么和呼叫 的SubmitChanges()。 在LINQ会生成一个SQL查询 含有WHERE [标题] IS NULL,以确保标题并没有被其他人修改。 在LINQ查找的属性 在映射[标题]。 在LINQ会发现[标题]不能为空。 在自[标题]不能为空,由 逻辑也绝不可能为空! 因此,优化查询,LINQ 用,其中0 = 1时,其替换 SQL相当于从不。 Now you change something and call SubmitChanges(). LINQ will generate a SQL query containing "WHERE [title] IS NULL", to make sure the title has not been changed by someone else. LINQ looks up the properties of [title] in the mapping. LINQ will find [title] NOT NULLable. Since [title] is NOT NULLable, by logic it never could be NULL! So, optimizing the query, LINQ replaces it with "where 0 = 1", the SQL equivalent of "never".

同样症状的时候会出现一个场的数据类型的数据类型不匹配的SQL,或如果字段丢失,因为LINQ将无法确保SQL数据还没有改变,因为读取数据。

The same symptom will appear when the data types of a field does not match the data type in SQL, or if fields are missing, since LINQ will not be able to make sure the SQL data has not changed since reading the data.