C # CODESMITH LINQ к SQL Westional Удалить работу
-
16-09-2020 - |
Вопрос
В проекте я работаю, мне нужно удалить «пользователь» из моей базы данных.Этот «пользователь» имеет две таблицы, которые ссылаются на внешний ключ.При жестком удалении я пытаюсь удалить все записи из таблицы 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 один элемент) .