可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
Error Message: Row not found or changed.
Stack Trace:
at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)
This occurs seemingly randomly. I get emailed these errors, and the URL reported always seems to work for me and should be functioning for everyone else as well.
I can fix this error by:
- Going to my
dbml
layout
- Selecting every field in the table causing conflicts
- Right click and set the property
Update Check
to Never
This seems to prevent these types of errors being thrown.
However, this is laborious to remember to keep doing whenever I make a chance to the dmbl
, add new tables, etc. Is there a better way to solve this problem? I'm getting maybe 50-100 of these a day which is bad for my visitors.
回答1:
Every time I've seen this error, it means that something changed in the database between the time that I loaded the record/object/whatever and when I was trying to save it. Without fail, it was because my unit of work was too big.
I don't know the exact nature of your application, but I'm assuming you are creating a data context, loading a record or list of records, performing some operations on it, chewing up some time and processor cycles, and then at the end trying to save the modified data back to the database. Maybe even loading an instance of a record/object and storing it in a class variable for a while, and then at the end of a page load or thread or whatever trying to save back anything that changed. The problem is that because LINQ stored a copy of that, that is the copy it wants to update. If the underlying data changes in the meantime, it gets mad.
Ask yourself this, what if you put a locking transaction on your data for the whole lifetime of your objects. Say anything you loaded any may modify, nobody else would be allowed to touch it during that time. Basically that is the assumption here. Granted, LINQ is a little more optimistic about it, no sense in locking the row or table if you may never be updating the data, but you think through those problems. Ask yourself what would break or slow down significantly if you were to put strict transactional locks on your objects, and that will probably point you to the offending code.
My solution to this is to keep my unit of work as small as possible. Don't load the object and use that as your working copy and store it back to the database, all in one context. Instead, load the object and pull out the info you need in one step, then figure out the changes you need to apply, and then load/update/save the object. Sure it causes more round trips to the database, but gives you a better assurance that you are working with the latest copy of data. It will still be "last in, wins", meaning that if someone made an update while you were working with the data it may be lost, but that is always a risk unless you lock the record with a transaction. However, it does buy you the flexiblity that if someone else is modifying unrelated fields in the same row, you both can operate on that data together.
回答2:
I had same issue, and solved it by comparing dbml to db structure. One property wasn't set to nullable, and that was causing the issue.
So check your dbml, and nullable properties.
回答3:
GetTable().Attach(newEntity, originalEntity);
If you're not using a version field to update, The above method parameterize new details and old details entities, if the original entity is changed at this point you'll still get the same error, this is up to you to ensure. This works like a charm, i've tried it.
回答4:
This can also happen if a database trigger changes any column in a row you are updating - even if you are not updating that particular column.
You will have to double check that any of the tables affected in your unit of work don't have triggers on them. If you are using update triggers, then you will probably want to make sure the updated columns are NeverCheck.
回答5:
Sometimes it's really simple... Make sure there are no locks on the table. In my case, the SQL Server Management Studio UI held locks that I didn't know about (didn't remember) while I was debugging. Unloading it cleared those locks and things started working again.
回答6:
Using SQL Profiler I tracked the SQL transactions towards my server and realized that on SubmitChanges()
the transmitted UPDATE
statement contains a wrong value in the WHERE
clause. This is because I have a property that looks like this:
class Position{
...
[Column]
public int Pieces{
get{
this.pieces = this.Transformers.Count;
return this.pieces;
}
set{ this.pieces = value; }
}
...
}
Since Transformers
is a List<Transformers>
element that represents a list of One-To-Many relations to another Transformers
table, I manually have to fill the List with each Transformer
that contains a foreign key to my Position
object. If, for some reason, I don't do that, then I will get the mentionned error because the Pieces
property is biased from the original value.
Thus, the SQL statement on SubmitChanges()
will search for an entry WHERE Pieces = somevalue
but the actual value of Pieces
in the entry is anothervalue
. So basically LINQ will think, that you changed something in the db meanwhile, because the db will return no value to this request.
As stated, one solution is:
[Column(UpdateCheck=UpdateCheck.Never)]
public int Pieces
{
get {
this.pieces= this.Transformers.Count;
return this.pieces;
}
set { this.pieces= value; }
}
Of course this can also be easily solved by setting up a simple getter function like
getPieces(){
return this.Transformers.Count();
}
and an "unbiased" property
class Position{
...
[Column]
public int Pieces{
get{ return this.pieces; }
set{ this.pieces = value; }
}
...
}
I hope this can be of help to somebody. I post this also because if somebody else had before, it'd have saved me hours of my life.
回答7:
I was getting this error on Windows Phone 8. And it took me a while to figure it out what the problem was. Basically it was this:
I had a class called TrackingInformation.
1. From a server I fetched an updated version of it.
2. My TileService updated the secondary tile with it's information and (!!) updated 1 property and saved it to the local database on the phone.
3. I tried to save the first instance of the object again and here I got the error "row not found or changed".
For me I just had to remove the 3rd part and it worked fine (I was already saved with the updated version). But since one property had changed it threw an exception...
I can't wait until EF7 comes to Windows Phone, so much headache with the current EF on WP8.
回答8:
updating linq to sql schema in designer resolve problem in my case