Pergunta

Em um projeto que eu estou trabalhando no que eu precisar excluir um "usuário" do meu banco de dados.Este "usuário" tem duas tabelas de referência é chave estrangeira.Quando eliminar estou tentando excluir todos os registros da Tabela A e Tabela B que tem chaves estrangeiras para o "usuário" e, em seguida, a exclusão de que "usuário" record.Tudo isso é feito dentro de repositórios e utilizar o objecto de fábrica.

O código é o seguinte:

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 cada tabela tem um registro, ele funciona bem.Se uma tabela possui múltiplas, o que só pode acontecer no UserToken e UserMappings, recebo o seguinte erro.

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)

Eu tinha que colocar em XXXX, por razões de privacidade.O que eu li isso como foi que no entanto o LINQ é armazenar preping as alterações para SQL coloca-lo em um Dicionário, e, de alguma forma, a chave para duas coisas é o mesmo e erros antes de ocorrer uma alteração.

Qualquer ajuda seria muito apreciada.

Foi útil?

Solução 2

Esta é uma velha questão, no entanto, nós nunca foram capazes de fazer isso eliminar a ambas as tabelas simultaneamente.Nossa solução foi eliminar a partir de um depois o outro e confirmar as alterações no meio.

Outras dicas

Eu estou um bocado tiro no escuro aqui, e assumindo a forma como você lê-lo é correto, juntamente com um pouco de dor que eu tive ao longo do caminho.

fazer as tabelas que você está excluindo de ter sua própria chave primária ou você está usando a chave estrangeira como o pk?(bem, você sabe o que quero dizer ...ela não soa como eles têm a sua própria e independente chave primária única que o linq é ciente de)'

o linq utiliza o método GetHash para a construção de um id exclusivo de campos de chave primária ..eu estou supondo que esses campos duplicados e, portanto, o dicionário problema ...o problema não é causado por 2 tabelas diferentes tenham o mesmo id da chave.

Eu estou supondo que estas tabelas com vários itens em uma espécie de no meio de um muitos-para-muitos associação.Uma rápida e suja correção seria adicionar um auto incremento de coluna para encontrar atribui isso a chave primária (caso contrário, tente usar um multi campo pk - eu não tenho;t tentei realmente com linq deliberatley).

Espero que isso lhe dá algumas idéias ...você pode substituir GetHashCode em uma classe parcial para corrigir o problema de outra maneira ...no entanto, você deve incluir apenas as partes dos dados que são invariantes através de um único item)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top