C#codesmith linqからSQL質問削除操作
-
16-09-2020 - |
質問
プロジェクトでは、データベースから「ユーザー」を削除する必要があります。この "user"には、外部キーを参照する2つのテーブルがあります。ハードを削除すると、表Aからのすべてのレコードを「ユーザー」に外部キーを持ち、その「ユーザー」レコードを削除してからすべてのレコードを削除しようとしています。これはすべてリポジトリ内で行われ、オブジェクトファクトリを使用しています。
コードは次のとおりです。
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());
}
.
各テーブルに1レコードがある場合は、うまく機能します。テーブルに複数のものがある場合は、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の変更の準備を記憶しているのと同様に、それを辞書に格納しています。
あらゆる助けが大いに評価されるでしょう。
解決 2
これは古い質問ですが、両方のテーブルを同時に両方のテーブルに削除することはできませんでした。私たちの解決策はもう一方から削除し、その間の変更をコミットします。
他のヒント
私はここで暗闇の中で撮影していて、あなたがそれをどのように読んだかを想定していると仮定しています私が途中で私が歩いていた小さな痛みと一緒に正しいです。
自分の主キーを使用しているテーブルを使用するか、PKとして外部キーを使用していますか。 (まああなたは私が何を意味するのか知っています...彼らがそれ自身の独立したユニークな主キーを持っているように聞こえません) '
LINQは、主キーフィールドから一意のIDを構築するためにGethashメソッドを使用します。これらのフィールドは、これらのフィールドが重複していること、したがって辞書の問題を推測しています...問題は、同じキーIDを持つ2つの異なるテーブルによって引き起こされません。
ここで複数のアイテムを持つこれらのテーブルは、多くの参加の中央にある種のものです。すばやく汚れた修正は、それらに自動インクリメント列を追加することです。
私はこれがあなたにいくつかのアイデアを与えることを願っています...あなたはあなたの問題を解決するために部分的なクラスでgethashcodeを上書きすることができました...しかしあなたは、不変のデータの部分だけを単一のアイテムに含めるべきです)