Data Conflict in LINQ
The error "Row not found or changed" also will appear sometimes when the columns or types in the O/R-Designer do not match the columns in the SQL database, especially if one column is NULLable in SQL but not nullable in the O/R-Designer.
So check if your table mapping in the O/R-Designer matches your SQL database!
These (which you could add in a partial class to your datacontext might help you understand how this works:
public void SubmitKeepChanges()
{
try
{
this.SubmitChanges(ConflictMode.ContinueOnConflict);
}
catch (ChangeConflictException e)
{
foreach (ObjectChangeConflict occ in this.ChangeConflicts)
{
//Keep current values that have changed,
//updates other values with database values
occ.Resolve(RefreshMode.KeepChanges);
}
}
}
public void SubmitOverwrite()
{
try
{
this.SubmitChanges(ConflictMode.ContinueOnConflict);
}
catch (ChangeConflictException e)
{
foreach (ObjectChangeConflict occ in this.ChangeConflicts)
{
// All database values overwrite current values with
//values from database
occ.Resolve(RefreshMode.OverwriteCurrentValues);
}
}
}
public void SubmitKeepCurrent()
{
try
{
this.SubmitChanges(ConflictMode.ContinueOnConflict);
}
catch (ChangeConflictException e)
{
foreach (ObjectChangeConflict occ in this.ChangeConflicts)
{
//Swap the original values with the values retrieved from the database. No current value is modified
occ.Resolve(RefreshMode.KeepCurrentValues);
}
}
}
Here's a way to see where the conflicts are (this is an MSDN example, so you'll need to heavily customize):
try
{
db.SubmitChanges(ConflictMode.ContinueOnConflict);
}
catch (ChangeConflictException e)
{
Console.WriteLine("Optimistic concurrency error.");
Console.WriteLine(e.Message);
Console.ReadLine();
foreach (ObjectChangeConflict occ in db.ChangeConflicts)
{
MetaTable metatable = db.Mapping.GetTable(occ.Object.GetType());
Customer entityInConflict = (Customer)occ.Object;
Console.WriteLine("Table name: {0}", metatable.TableName);
Console.Write("Customer ID: ");
Console.WriteLine(entityInConflict.CustomerID);
foreach (MemberChangeConflict mcc in occ.MemberConflicts)
{
object currVal = mcc.CurrentValue;
object origVal = mcc.OriginalValue;
object databaseVal = mcc.DatabaseValue;
MemberInfo mi = mcc.Member;
Console.WriteLine("Member: {0}", mi.Name);
Console.WriteLine("current value: {0}", currVal);
Console.WriteLine("original value: {0}", origVal);
Console.WriteLine("database value: {0}", databaseVal);
}
}
}
To make it ignore the problem and commit anyway:
db.SubmitChanges(ConflictMode.ContinueOnConflict);
I've gotten this error in a circumstance completely unrelated to what the error message describes.
What I did was load a LINQ object via one DataContext, and then tried to SubmitChanges() for the object via a different DataContext - gave this exact same error.
What I had to do was call DataContext.Table.Attach(myOldObject), and then call SubmitChanges(), worked like a charm.
Worth a look, especially if you're of the opinion that there really shouldn't be any conflicts at all.