In a project I am working on I need to delete a "user" from my database. This "user" has two tables that reference it's foreign key. When hard deleting I am trying to delete all records from Table A and Table B that have foreign keys to the "user" and then deleting that "user" record. This is all done within repositories and using object factory.
The code is as follows:
public void RemoveUserByUserId(int userId)
{
var user = m_context.User.GetByKey(userId);
ObjectFactory.Inject(m_context);
UserTokenRepository.RemoveUserTokensByUserId(userId);
UserMappingRepository.RemoveUserMappingsByUserId(userId);
m_context.User.DeleteOnSubmit(user);
m_context.SubmitChanges();
ObjectFactory.ResetDefaults();
}
public static void RemoveUserTokensByUserId(int userId)
{
var dataContext = ObjectFactory.GetInstance<DataContext>();
var userTokens = dataContext.UserToken.ByUserId(userId);
dataContext.UserToken.DeleteAllOnSubmit(userTokens.AsEnumerable());
}
public static void RemoveUserMappingsByUserId(int userId)
{
var dataContext = ObjectFactory.GetInstance<DataContext>();
var userMappings= dataContext.UserMapping.ByUserId(userId);
dataContext.UserMapping.DeleteAllOnSubmit(userMappings.AsEnumerable());
}
If each table has one record, it works fine. If a table has multiple, which can only happen on the UserToken and UserMappings, I get the following error.
System.ArgumentException was unhandled by user code
Message=An item with the same key has already been added.
Source=mscorlib
StackTrace:
at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)
at System.Collections.Generic.Dictionary`2.Insert(TKey key, TValue value, Boolean add)
at System.Data.Linq.ChangeProcessor.EdgeMap.Add(MetaAssociation assoc, TrackedObject from, TrackedObject to)
at System.Data.Linq.ChangeProcessor.BuildEdgeMaps()
at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)
at XXXX.XXXX.XXXX.XXXXDataContext.SubmitChanges(ConflictMode failureMode) in XXXX:line 519
at System.Data.Linq.DataContext.SubmitChanges()
at XXXX.UserRepository.RemoveUserByUserId(Int32 userId) in XXXX:line 146
at XXXX(Int32 profileUserId) in XXXX:line 948
at XXXX(Int32 profileUserId) in XXXX:line 165
at SyncInvokeUnregisterUserForActivationFailed(Object , Object[] , Object[] )
at System.ServiceModel.Dispatcher.SyncMethodInvoker.Invoke(Object instance, Object[] inputs, Object[]& outputs)
at System.ServiceModel.Dispatcher.DispatchOperationRuntime.InvokeBegin(MessageRpc& rpc)
I had to put in XXXX for privacy reasons. What I read this as was that however LINQ is storing preping the changes for SQL it puts it into a Dictionary, and somehow the key for two things is the same and it errors before a change occurs.
Any help would be much appreciated.
This is an old question however we were never able to make this delete to both tables simultaneously. Our solution was to delete from one then the other and commit the changes in between.