.net 使用Linq to Sql对象进行更新时遇到问题

.net 使用Linq to Sql对象进行更新时遇到问题,.net,linq-to-sql,optimistic-concurrency,.net,Linq To Sql,Optimistic Concurrency,我有一个简单的linq到sql对象。我从数据库中获取它并更改一个字段,然后保存 未更新任何行:( 当我检查通过线路发送的完整Sql代码时,我注意到它不是通过主键而是通过where子句在所有字段上对行进行更新。这正常吗?我原以为使用主键上的where子句链接而不是where'ing(这是一个字:p)来更新字段会很容易在每个领域 这是密码 using (MyDatabase db = new MyDatabase()) { var boardPost = (from bp in db.Boa

我有一个简单的linq到sql对象。我从数据库中获取它并更改一个字段,然后保存

未更新任何行:(

当我检查通过线路发送的完整Sql代码时,我注意到它不是通过主键而是通过where子句在所有字段上对行进行更新。这正常吗?我原以为使用主键上的where子句链接而不是where'ing(这是一个字:p)来更新字段会很容易在每个领域

这是密码

using (MyDatabase db = new MyDatabase())
{
    var boardPost = (from bp in db.BoardPosts
        where bp.BoardPostId == boardPostId
        select bp).SingleOrDefault();

    if (boardPost != null &&
        boardPost.BoardPostId > 0)
    {
        boardPost.ListId = listId; // This changes the value from 0 to 'x'
        db.SubmitChanges();
    }
}
下面是一些sql示例

exec sp_executesql N'UPDATE [dbo].[BoardPost]
SET [ListId] = @p6
WHERE ([BoardPostId] = @p0) AND .... <snip the other fields>',N'@p0 int,@p1 int,@p2 nvarchar(9),@p3 nvarchar(10),@p4 int,@p5 datetime,@p6 int',@p0=1276,@p1=212787,@p2=N'ttreterte',@p3=N'ttreterte3',@p4=1,@p5='2009-09-25 12:32:12.7200000',@p6=72
exec sp_executesql N'UPDATE[dbo].[BoardPost]
SET[ListId]=@p6
其中([BoardPostId]=@p0)和…,N'@p0-int,@p1-int,@p2-nvarchar(9),@p3-nvarchar(10),@p4-int,@p5-datetime,@p6-int',@p0=1276,@p1=212787,@p2=N'tReterte',@p3=N'tReterte3',@p4=1,@p5=2009-09-25 12:32:12.7200000',@p6=72
现在,我知道这个更新中有一个datetime字段..当我检查DB时,它的值是/是'2009-09-25 12:32:12.720'(小于零,大于上)…所以我不确定这是否会弄乱where子句条件

但是仍然!它应该在PK上做一个where子句吗?如果有的话。为了速度

是/否


更新

在阅读了nitzmahone的回复后,我尝试在一些值上玩乐观并发,但仍然不起作用:(

于是我开始了一些新的东西……乐观并发发生了,它在试图更新的字段上包含了where子句。当这种情况发生时,它就不起作用了

所以..在上面的sql中,where子句如下所示

WHERE ([BoardPostId] = @p0) AND ([ListId] IS NULL) AND ... <rest snipped>)
其中([BoardPostId]=@p0)和([ListId]为空)和…)
这听起来不对!在我进行更新之前,DB中的值为null。但是当我将ListId值添加到where子句时(或者更确切地说,当L2S由于optomistic concurrecy而添加它时),它无法找到/匹配该行


wtf?

where子句内容是正常的-如果你不知道为什么,谷歌“乐观并发”。你可以通过在dbml设计器中将所有字段设置为“UpdateCheck:Never”来选择退出该行为(但要知道这样做是放弃了一项重要的安全检查)


更新失败的事实很可能是由于DBML和DB之间的数据类型或源值不匹配(它们很容易不同步-有第三方工具可以将DBML与DB进行这种比较)。要进行测试,请尝试运行在SSMS中捕获的update语句,但从where子句中删除值,直到获得“1行受影响”。一旦它起作用,您就找到了问题列。

where子句内容是正常的-如果您不知道原因,请使用谷歌“乐观并发”。您可以通过在dbml设计器中将所有字段设置为“UpdateCheck:Never”来选择退出该行为(但要知道,这样做会放弃一项重要的安全检查)


更新失败的事实很可能是由于DBML和DB之间的数据类型或源值不匹配(它们很容易不同步-有第三方工具可以将DBML与DB进行比较)。要进行测试,请尝试运行在SSMS中捕获的update语句,但从where子句中删除值,直到获得“1行受影响"。一旦它工作,您就找到了问题列。

您描述的行为表明您的数据库和Linq to SQL对象已不同步。您应该尝试从Linq to SQL类设计器中删除该类,保存,将表从数据库资源管理器拖回设计器中,然后再次保存。这应该清除更新问题已解决。

您描述的行为表明您的数据库和Linq to SQL对象已不同步。您应该尝试从Linq to SQL类设计器中删除该类,保存,将表从数据库资源管理器拖回设计器中,然后再次保存。这应该会解决更新问题。

请尝试将其置于
submitchanges()之前


请尝试将其置于
submitchanges()之前


嗨,尼茨,我已经更新了原来的帖子。你能看一下吗?我已经根据你的评论在这里更新了。你上面的代码评论说“将值从0更改为x”-如果它真的是0(而不是null),这是您的问题-该列或服务器数据类型上的DBML的Nullable属性不匹配。如果它在DB中确实为Nullable,请确保设计器中的Nullable属性为true,并且服务器数据类型属性不是“NOT NULL”@Nitz-如果我决定不使用乐观并发并将所有字段的行为更改为“UpdateCheck:Never”,我是否需要在主键字段上执行此操作?如果我这样做,L2S是否足够聪明,可以通过PK进行更新,那么?应该这样做-尽管现在正在使用PK进行更新(查询优化器对此进行了分析).这是L2S工作的唯一方式-它不会让你在没有PK的情况下更新表。OC不会在性能方面花费你任何东西-只要意识到关闭它,如果有其他东西更新了你想要更改的记录,你就会盲目地覆盖更改,永远不会知道。OC是在你吹走其他更改之前警告你s(不需要像悲观并发一样锁定记录,你也可以通过执行可序列化的tx来锁定L2S)。嗨,尼茨,我已经更新了原始帖子。你能看看吗?我已经根据你的评论在这里更新了它。你上面的代码评论说“将值从0更改为x”-如果它真的是0(而不是null),这是您的问题-该列或服务器数据类型上的DBML的Nullable属性不匹配。如果它在DB中确实为Nullable,请确保设计器中的Nullable属性为true,并且服务器数据类型属性不是“NOT NULL”@Nitz—如果我决定不使用乐观并发并将所有字段的行为更改为“更新”
_tdIssuesLog.Refresh(System.Data.Linq.RefreshMode.KeepCurrentValues, issueslog);