简单语句中的LINQ C#错误:行未找到或更改

20

首先,这不可能是多用户问题,因为我正在本地开发版本的数据库上工作。

当我执行db.SubmitChanges()时,会出现不太具说明性的“未找到或更改行”的错误。如果在SubmitChanges()发生之前刚好中断执行,我可以在SQL Server Management Studio中检查到该行确实存在

以下是整个函数的代码,以供任何想要帮助的人放入上下文,但问题行在最后(第48行)。

更新 这真的很奇怪:更新matchingTrans.Url(请参见代码的倒数第二行)会导致错误。即使匹配的matchingTrans.Title仍然被更新,注释掉这一行也不会引发错误。

private static void MenuItemUpdate(int languageId, NavigationItem item)
{
    using (var db = DataContextFactory.Create<MyDataContext>())
    {
        // Select existing menu item from database.
        var dbItem =
            (from i in db.MenuItems
             where i.Id == item.Id
             select i).Single();
        // Obtain ID of link type.
        dbItem.FkLinkTypeId = GetLinkTypeByName(
            Enum.GetName(typeof (NavigationItemLinkType), item.LinkType)).Id;
        // Update the Link field with what is given.
        dbItem.Link = item.Link;
        db.SubmitChanges();

        // Item already exists and needs editing.
        // Get associated translations.
        var trans =
            from t in db.MenuItemTranslations
            where t.FkMenuItemId == item.Id
            select t;

        // If translation exists for given language, edit it.
        var matchingTrans =
            (from t in trans
             where t.FkLanguageId == languageId
             select t).SingleOrDefault();

        if (matchingTrans == null)
        {
            // No matching translation - add one.
            var newDbTrans = new MenuItemTranslation
            {
                FkMenuItemId = item.Id,
                FkLanguageId = languageId,
                Title = item.Title,
                Url = item.FriendlyUrl
            };
            db.MenuItemTranslations.InsertOnSubmit(newDbTrans);
            db.SubmitChanges();
        }
        else
        {
            // Matching translation - edit it.
            matchingTrans.Title = item.Title;
            matchingTrans.Url = item.FriendlyUrl;
            db.SubmitChanges();
            // WTF ERROR: Row not found or changed.
        }
    }
}

你有SQL Profiler吗?如果有的话,我会查看SQL在数据库上实际执行了什么以及数据库对此的处理情况。另外,在你的MenuItemTranslations中主键是什么? - Ian Griffiths
@Ian Griffiths 谢谢你的信息,我会看看 SQL Profiler。顺便说一下,主键是 Id。 - Greg
4个回答

49

通过查看SQL Profiler的输出,我得以找到答案。有一段错误的SQL代码是以 WHERE 0 = 1 结尾的...这很明显是一个错误。

事实证明,另一位开发人员只是将该字段更改为允许为空,但Linq-to-SQL文件没有相应地进行更新。

简而言之,如果提示 行未找到或已更改 错误信息似乎毫无道理,请确保你的数据库架构与.dbml文件完全匹配,否则你会在任何字段上出现略有不同的架构而导致此错误。


3
你应该将这个标记为答案,否则寻找未回答问题的人会来到这里尝试提供帮助,却发现你已经解决了问题... - Shaul Behr
4
我刚遇到了同样的问题,只不过我是那个愚蠢的开发者,改变了允许空值属性,分心了一下,现在才意识到我忘记更新我的模型了。 - Splunk
1
这是我第二次遇到这个问题,也是多亏了你解决了它。如果可以的话,我会再给你一个+1的赞。 - jahu
我还不确定,但看起来在我的情况下,varchar长度是导致这个问题的原因。 - ahsant

3

请查看SQL Server服务器级别的连接属性“无计数”

1.在对象资源管理器中,右键单击SQL Server连接-->属性
2.转到连接选项卡/页面
3.查找默认连接选项“无计数”
4.确保此选项未被选中。


2

在这里,我发现另一种可能性可以添加到已经出色的答案列表中:

当使用一个非空列在数据库中,然后将其映射到本质上可为空的数据类型(在这个示例中,数据库类型为LONG BLOB NOT NULL,映射到C#中的字节数组)时,您可能会遇到更新数据库与完全相同的字节数组引起抛出此错误的情况。

例如:您有一个网站,允许用户将图像上传到数据库。您的表具有不可为空的blob(在SQL Server中为image,等等)。用户选择使用已经存在的完全相同的图像来更新记录。更新检查将失败。我通过首先执行.SequenceEqual() 检查,然后仅在传入的字节数组与现有字节数组不相同时才调用上下文对象上的.SubmitChanges() 方法来修复此问题。


1

即使数据库架构和dbml完全匹配,我仍然遇到了这个问题。问题在于我试图在单个SubmitChanges语句中更改实体并插入实体。我通过对每个操作进行SubmitChanges而不是一次性全部提交来解决了这个问题。

这都是在事务范围内完成的,所以可能与此有关,但我不确定。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接