Question

Dans un projet, je travaille sur j'ai besoin de supprimer un "utilisateur" de ma base de données.Cet "utilisateur" a deux tables qui font référence à sa clé étrangère.Lorsque la suppression dure, j'essaie de supprimer tous les enregistrements du tableau A et du tableau B qui ont des clés étrangères sur "l'utilisateur", puis supprimant cet enregistrement "utilisateur".Tout cela est fait dans les référentiels et utilise l'usine d'objet.

Le code est comme suit:

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());
}

Si chaque table a un enregistrement, cela fonctionne bien.Si une table a plusieurs, ce qui ne peut se produire que sur les USERTOCK et UERERMAPPINGS, je reçois l'erreur suivante.

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)

Je devais mettre en avant XXXX pour des raisons de confidentialité.Ce que je lis ceci comme si cependant, Linq stocke la préparation des modifications de SQL, il le met dans un dictionnaire et la clé de deux choses est la même et les erreurs informatiques avant qu'un changement ne se produise.

Toute aide serait très appréciée.

Était-ce utile?

La solution 2

Ceci est une vieille question, mais nous n'avons jamais été en mesure de faire cette suppression aux deux tables simultanément.Notre solution consistait à supprimer d'un puis à l'autre et à commettre les changements entre les deux.

Autres conseils

Je suis un peu tourné dans le noir ici et en supposant comment vous lisez, c'est correct avec une petite douleur que j'ai eue sur le chemin.

Les tables que vous supprimez ont-elles une clé primaire ou utilisez-vous la clé étrangère comme la PK? (Eh bien, vous savez ce que je veux dire ... cela ne semble pas avoir sa propre clé primaire unique indépendante que Linq est au courant) '

LINQ utilise la méthode gethash pour construire un identifiant unique à partir des champs de clé primaire .. Je suppose que ces champs en double et donc le problème du dictionnaire ... Le problème n'est pas causé par 2 tables différentes ayant le même identifiant de clé.

Je suppose que ces tables avec plusieurs articles dans sont une sorte de jointure au milieu d'un grand nombre de joints. Un correctif rapide et sale serait d'ajouter une colonne d'incrémentation automatique pour leur attribution à la touche principale (sinon, essayez d'utiliser un pk multi-champs - que je n'ai pas vraiment essayé avec Linq Deliberatley).

J'espère que cela vous donne quelques idées ... Vous pouvez remplacer gethashcode dans une classe partielle pour résoudre votre problème un autre moyen ... Toutefois, vous ne devez inclure que les parties de vos données qui sont invariantes accrochent un seul article)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top