Pregunta

En un proyecto, estoy trabajando en necesito eliminar un "usuario" de mi base de datos.Este "usuario" tiene dos tablas que hacen referencia a su clave externa.Cuando se elimina con dificultad, estoy tratando de eliminar todos los registros de la Tabla A y la Tabla B que tienen claves externas al "Usuario" y luego eliminando ese registro "Usuario".Todo esto se hace dentro de los repositorios y usando Fábrica de objetos.

El código es el siguiente:

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 cada tabla tiene un registro, funciona bien.Si una tabla tiene múltiples, lo que solo puede suceder en los USERToken y USERMAlpings, obtengo el siguiente error.

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)

Tuve que poner en XXXX por razones de privacidad.Lo que leí esto como era, sin embargo, LINQ está almacenando preparando los cambios para SQL, lo pone en un diccionario, y de alguna manera la clave para dos cosas es la misma y errores de TI antes de que ocurra un cambio.

Cualquier ayuda sería muy apreciada.

¿Fue útil?

Solución 2

Esta es una pregunta antigua, sin embargo, nunca pudimos hacer que se eliminen a ambas tablas simultáneamente.Nuestra solución fue eliminar de una que la otra y comprometer los cambios en el medio.

Otros consejos

Estoy un poco disparando en la oscuridad aquí y asumiendo cómo leísla, es correcto junto con un poco de dolor que he tenido en el camino.

¿Las tablas que está eliminando tienen su propia clave principal o está utilizando la clave externa como la PK? (Bueno, sabes lo que quiero decir ... no suena como si tuvieran su propia clave primaria única independiente que Linq es consciente de) '

LINQ usa el método GetHash para construir una identificación única de los campos de la clave principal. Estoy adivinando que estos campos duplican y, por lo tanto, el problema del diccionario ... El problema no es causado por 2 tablas diferentes que tienen la misma ID de tecla.

Estoy adivinando que estas mesas con múltiples elementos son una especie de en medio de muchos a muchos unirse. Una solución rápida y sucia sería agregar una columna de incremento automático a ellos. ND Asigne esto a la tecla principal (de lo contrario, intente usar un PK Multi Field, que no he probado realmente con Linq Deliberatley).

Espero que esto le dé algunas ideas ... podría anular GetHashCode en una clase parcial para solucionar su problema de otra manera ... Sin embargo, solo debe incluir las partes de sus datos que son invariantes de un solo elemento)

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top