В проекте, над которым я работаю, мне нужно удалить «пользователя» из моей базы данных.У этого «пользователя» есть две таблицы, которые ссылаются на его внешний ключ.При жестком удалении я пытаюсь удалить все записи из таблицы A и таблицы B, имеющие внешние ключи для «пользователя», а затем удаляю эту «пользовательскую» запись.Все это делается в репозиториях и с использованием фабрики объектов.
Код выглядит следующим образом:
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, он помещает его в словарь, и почему-то ключ к двум вещам одинаков, и он ошибается до того, как произойдет изменение.
Любая помощьочень цениться.