Domanda

In un progetto sto lavorando ho bisogno di eliminare un "utente" dal mio database.Questo "utente" ha due tabelle che fanno riferimento alla chiave straniera.Quando il duro eliminazione sto cercando di eliminare tutti i record dalla tabella A e dalla tabella B che hanno tasti estranei per "utente" e quindi eliminare il record "utente".Questo è tutto fatto all'interno dei repository e utilizzando l'oggetto Factory.

Il codice è il seguente:

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

Se ogni tabella ha un record, funziona bene.Se una tabella ha più, il che può accadere solo sui userroken e negli usermapping, ottengo il seguente errore.

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

Ho dovuto inserire xxxx per motivi di privacy.Ciò che ho letto così come è stato che Linq memorizza la preparazione delle modifiche per SQL lo mette in un dizionario, e in qualche modo la chiave per due cose sono gli stessi e gli errori IT prima che si verifichi un cambiamento.

Qualsiasi aiuto sarebbe molto apprezzato.

È stato utile?

Soluzione 2

Questa è una vecchia domanda Tuttavia non siamo mai stati in grado di effettuare questa eliminazione a entrambe le tabelle contemporaneamente.La nostra soluzione era di eliminare da una poi l'altra e commettere i cambiamenti in mezzo.

Altri suggerimenti

Sono un po 'sparando nel buio qui e supponendo come la leggi è corretto insieme a un po' di dolore che ho avuto lungo la strada.

Le tabelle che si stanno eliminando hanno la propria chiave primaria o stai usando la chiave straniera come PK? (Beh, sai cosa intendo ... non sembra che abbiano la propria chiave primaria unica indipendente che Linq è a conoscenza di) '

LINQ utilizza il metodo GetHash per costruire un ID univoco dai campi chiave primari. Indovina che questi campi duplicati e quindi il problema del dizionario ... il problema non è causato da 2 diverse tabelle con lo stesso ID chiave.

Indovina che queste tabelle con più oggetti sono una specie di nel mezzo di molti a molti unire. Una soluzione rapida e sporca sarebbe quella di aggiungere una colonna di incremento automatico a loro nd assegnare questo al tasto primario (altrimenti tenta di utilizzare un multi campo PK - che non ho provato davvero con Linq Delliberatley).

Spero che questo ti dà alcune idee ... potresti sovrascrivere GetHashCode in una classe parziale per risolvere il tuo problema in un altro modo ... Tuttavia, tuttavia dovresti includere solo le parti dei tuoi dati che sono invarianti accrossano un singolo oggetto) .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top