Вопрос

В проекте я работаю, мне нужно удалить «пользователь» из моей базы данных.Этот «пользователь» имеет две таблицы, которые ссылаются на внешний ключ.При жестком удалении я пытаюсь удалить все записи из таблицы A и Table 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 и USERMAUPINGS, я получаю следующую ошибку.

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)
.

Мне пришлось поставить в хххх по причинам конфиденциальности.То, что я прочитал это, как это было, однако LINQ хранит подготовление изменений для SQL, он помещает его в словарь, и как-то ключ для двух вещей - это одинаково, и она ошибками, прежде чем происходит изменение.

Любая помощь будет очень ценится.

Это было полезно?

Решение 2

Это старый вопрос, однако мы никогда не смогли сделать это удаление для обоих таблиц одновременно.Наше решение было удаление от одного затем другого и совершать изменения между между ними.

Другие советы

Я вроде стрельбу в темноте здесь и предполагая, как вы читаете, правильно вместе с небольшим болью, которую я имел по пути.

Выполните таблицы, которые вы удалеете, есть свой основной ключ или используете внешний ключ в качестве PK? (Ну, вы знаете, что я имею в виду ... это не звучит так, будто у них есть свой независимый уникальный первичный ключ, что linq знает) '

linq использует метод gethash для создания уникального идентификатора из первичных полей основных ключей. Я предполагаю, что эти поля дублируют и, следовательно, проблема словаря ... Проблема не вызывается 2 различными таблицами, имеющими один и тот же идентификатор ключа.

Я предполагаю, что эти таблицы с несколькими элементами в своем роде в середине множества соединения. Быстрая и грязное исправление было бы, чтобы добавить столбец AUTO SCREMPY на них, ND назначить это к первичному ключу (в противном случае попробуйте использовать мульти поле PK - который я не вырезал с LINQ Develiberatle).

Я надеюсь, что это дает вам некоторые идеи ... Вы можете переопределить GetHashCode в частичном классе, чтобы исправить вашу проблему другим способом ... Однако вы должны включать только части ваших данных, которые являются инвариантными Accross один элемент) .

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top