В проекте, над которым я работаю, мне нужно удалить «пользователя» из моей базы данных. Этот «пользователь» имеет две таблицы, которые ссылаются на внешний ключ. При жестком удалении я пытаюсь удалить все записи из таблицы A и таблицы B, которые имеют внешние ключи к «пользователю», а затем удаляют эту «пользовательскую» запись. Все это делается в хранилищах и с использованием фабрики объектов.C# CodeSmith LINQ to SQL question DELETE Операция
Код выглядит следующим образом:
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());
}
Если каждая таблица имеет одну запись, она отлично работает. Если таблица имеет несколько, что может произойти только в UserToken и UserMappings, я получаю следующую ошибку.
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)
Мне пришлось установить XXXX по соображениям конфиденциальности. То, что я читал, так это то, что LINQ хранит предварительные изменения для SQL, он помещает его в словарь, и как-то ключ к двум вещам один и тот же, и ошибки перед тем, как произойдет изменение.
Любая помощь будет высоко оценена.
Фактически каждая таблица имеет первичный ключ. структура выглядит следующим образом. Таблица пользователя [pk: user_id] Таблица UserToken - [pk: token_id (guid)] [fk: user_mapping_id] [fk: user_id] Таблица UserMapping - [pk: user_mapping_id] [fk: user_id] –