I have a method on a data context that takes an object, calls attach to match it with its database entry, refresh and submit any of the changes i make to the object. The update works fine the first time but when i try to update the same entry a second time it starts throwing an exception. Here is whats in my update method:
this.GetTable(data.GetType()).Attach(data, false);
this.Refresh(RefreshMode.KeepCurrentValues, data);
this.SubmitChanges();
Here is the stack trace from the exception:
System.Data.Linq开发者_StackOverflow中文版.DuplicateKeyException: Cannot add an entity with a key that is already in use.
at System.Data.Linq.Table`1.Attach(TEntity entity, Boolean asModified)
at System.Data.Linq.Table`1.System.Data.Linq.ITable.Attach(Object entity, Boolean asModified)
Am I missing some sort of table refresh?
When you update the entity the second time, are you attaching it to the same DataContext instance? If you are, that's why the exception is being thrown. You only need to attach an entity once during the lifetime of the DataContext.
Confirm
data
is not fromthis
I suspect the instance you are trying to attach (
data
) is from the same context you are attaching to (i.e.this
). You don't need to attach if it is from the same instance (it will simply update when youSubmitChanges()
thanks to change tracking. If your code above is part of a method, let's call itAttachAndSave()
, you can't call it with data you retrieved from that context, or call it twice in a row with the same data as it will try and attach the same data twice.If
data
is from a different DataContext, try using theasModified
parameter:this.GetTable(data.GetType()).Attach(data, true);
My suspicion if point 1. doesn't help is that SQL is determining that you want to insert a new instance rather than modify an existing one, and it's then throwing an exception because your instance has the same Primary Key as another existing instance (i.e. the one you are trying to update). However, this will require a timestamp tracking field, and is unlikely to be the cause. Point 1 above (attaching an instance belonging to the current context) is most likely your issue.
精彩评论