1

私が取り組んでいるプロジェクトでは、データベースから「ユーザー」を削除する必要があります。この「ユーザー」には、外部キーを参照する2つのテーブルがあります。ハード削除するとき、「ユーザー」への外部キーを持つテーブル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());
}

各テーブルに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つのキーは同じであり、変更が発生する前にエラーが発生します。

どんな助けでも大歓迎です。

4

2 に答える 2

0

これは古い質問ですが、両方のテーブルを同時に削除することはできませんでした。私たちの解決策は、一方から他方を削除し、その間に変更をコミットすることでした。

于 2012-02-16T21:30:03.283 に答える
0

私はここでちょっと暗闇の中で撮影していて、あなたがそれを読む方法が正しいと仮定して、途中で少し苦痛を感じました。

削除するテーブルには独自の主キーがありますか、それとも外部キーをpkとして使用していますか?(私が何を意味するかはご存知でしょう... linqが認識している独自の独立した一意の主キーを持っているようには聞こえません)」

linqはGetHashメソッドを使用して、主キーフィールドから一意のIDを構築します..これらのフィールドが重複しているため、ディクショナリの問題が発生していると推測しています...この問題は、同じキーIDを持つ2つの異なるテーブルが原因ではありません。

複数の項目が含まれるこれらのテーブルは、多対多の結合の中間にあると思います。手っ取り早い修正は、自動インクリメント列をそれらに追加し、これを主キーに割り当てることです(それ以外の場合は、マルチフィールドpkを使用してみてください-私は実際にはlinqdeliberatleyで試していません)。

これでいくつかのアイデアが得られることを願っています...部分クラスでGetHashCodeをオーバーライドして、別の方法で問題を修正できます...ただし、単一のアイテム間で不変であるデータの部分のみを含める必要があります)

于 2010-07-15T18:14:55.600 に答える