简体   繁体   中英

LINQ to SQL - “Row not found or changed” when updated using OnPropertyChanged

The Save method in the following code is failing with the error "Row not found or changed".

Question question = questionService.getQuestionById(id); 
// returning Context.Question.Where(q => q.id == id).SingleOrDefault()

question.Text = "some text";

questionService.Save(question); 
// Context.SubmitChanges();

Question is a DTO generated using CodeSmith and PLINQO templates. However, the "Row not found or changed" error only occurs aftering implementing a custom override to the OnPropertyChanged event to automatically insert when a record was created or modified. I profiled the queries that were generated, when the getQuestionById method is executed, it is executing a normal select statement. However, if the modified date is returned as '2012-07-28 12:15:00.900', when I attempt to save the record, the update is failing because it is adding Modified = '2012-07-28 12:15:00.903' to the update statement, which is a few milliseconds different from what exists in the database. So I know this has something to do with the following code added to the generated Question object:

protected override void OnPropertyChanged(string property)
{
    this.UpdateProperties(property);
    base.OnPropertyChanged(property);
}

public static void UpdateProperties(this object updatedObject, string property)
{
    if (property == created || property = modified) return;
    // prevents an infinite loop 

    Update(updateObject);
    // sets updatedObject.Created and updateObject.Modified fields
}

I have found a few posts that suggest setting the UpdateMode to never in the dbml for fields that use higher precision than seconds. I can use this as a last resort, but I have been adding the same code to other tables with the same data types for a while without any problems and would like to understand why it is only happening for this one table. This also seems to fail somewhat randomly, I don't have specific steps to reproduce it, but it does seem to happen more frequently when I am not debugging.

My guess is you're using your Modified (and/or Created) column in the database to check for concurrency. You are also updating this column yourself. This mix is not correct.

A better way is to use a timestamp as the concurrency-check-column. This column will be set by SQL server (assuming this is what you are using), and is not a date-time but some internal unique database generated value.

Some googling gave me this article which I think will explain the basics well on how to set up your timestamp column.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM