Row not found or changed LINQ C# error on simple statement

Greg picture Greg · Nov 5, 2010 · Viewed 20.5k times · Source

First of all, there is no chance that this is a multi-user issue, as I'm working locally on a dev version of the database.

I am getting the not very explanatory Row not found or changed error being thrown when I perform db.SubmitChanges(). If I break the execution just before the SubmitChanges() occurs, I can check in SQL Server Management Studio and the row does exist!

Here's the code for the whole function, just to put it in context for anyone who wants to help, but the problem line is right at the end (line 48).

Update This is a really odd one: the error is caused by updating matchingTrans.Url (see penultimate line of code). Commenting out this line doesn't throw the error - even if the matchingTrans.Title still gets updated.

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.
        }
    }
}

Answer

Greg picture Greg · Nov 5, 2010

Looking at the SQL Profiler output, it helped me figure out the answer to this. There was a bad piece of SQL being generated which ended with WHERE 0 = 1 ... an obvious error.

It turns out that the field had simply been changed to allow nulls by another developer, and the Linq-to-SQL file hadn't been updated accordingly.

In short, if the Row not found or changed error message appears to be generated for no reason, make sure your database schema exactly matches your .dbml file else you'll get this error message on any fields that have slightly differing schemas.