Pergunta

Eu não tenho trabalhado em SQL muito tempo, mas eu pensei que eu entendi que por declarações de embrulho SQL dentro de uma transação, todas as declarações concluída, ou nenhum deles fez. Aqui está o meu problema. Eu tenho um objeto para que tem uma coleção LineItem. Os itens de linha estão relacionados na order.OrderId. Tenho verificado que todas as identificações são definidos e estão corretas , mas quando eu tentar salvar (insert) a ordem que eu estou recebendo A instrução INSERT em conflito com o ESTRANGEIRO KEY restrição "FK_OrderItemDetail_Order". O conflito ocorreu no banco de dados "MyData", tabela "dbo.Order", a coluna 'OrderId'.

código pseudo:

create a transaction
transaction.Begin()
Insert order
Insert order.LineItems <-- error occurs here
transaction.Commit

código real:

...
entity.Validate();
if (entity.IsValid)
{
    SetChangedProperties(entity);
    entity.Install.NagsInstallHours = entity.TotalNagsHours;
    foreach (OrderItemDetail orderItemDetail in entity.OrderItemDetailCollection)
    {
        SetChangedOrderItemDetailProperties(orderItemDetail);
    }
    ValidateRequiredProperties(entity);
    TransactionManager transactionManager = DataRepository.Provider.CreateTransaction();
    EntityState originalEntityState = entity.EntityState;
    try
    {
        entity.OrderVehicle.OrderId = entity.OrderId;
        entity.Install.OrderId = entity.OrderId;
        transactionManager.BeginTransaction();

        SaveInsuranceInformation(transactionManager, entity);
        DataRepository.OrderProvider.Save(transactionManager, entity);
        DataRepository.OrderItemDetailProvider.Save(transactionManager, entity.OrderItemDetailCollection);             if (!entity.OrderVehicle.IsEmpty)
        {
            DataRepository.OrderVehicleProvider.Save(transactionManager, entity.OrderVehicle);
        }
        transactionManager.Commit();
    }
    catch
    {
        if (transactionManager.IsOpen)
        {
            transactionManager.Rollback();
        }
        entity.EntityState = originalEntityState;
    }
}
...

Alguém sugeriu que eu preciso usar duas transacções, uma para o fim, e um para os itens de linha, mas estou razoavelmente certo de que é errado. Mas eu tenho lutado contra isso há mais de um dia e agora eu preciso para resolvê-lo para que eu possa seguir em frente mesmo que isso signifique usando um em torno do trabalho ruim. Estou talvez apenas fazendo algo estúpido?

Foi útil?

Solução

Eu notei que você disse que estava usando NetTiers para sua geração de código.

Eu usei NetTiers mim e descobriram que se você excluir a sua restrição de chave estrangeira de sua tabela, adicioná-lo de volta para a mesma mesa e, em seguida, executar os scripts para criar NetTiers novamente depois de fazer as alterações no poder de banco de dados ajuda de reset a camada de acesso a dados. Eu tentei isso na ocasião com resultados positivos.

Boa sorte com o seu problema.

Outras dicas

Sem ver seu código, é difícil dizer qual é o problema. Poderia ser qualquer número de coisas, mas olhar para estes:

  1. Isto é óbvio, mas seus dois comandos de inserção estão na mesma conexão (e as estadias conexão aberta o tempo todo) que possui o direito transação?
  2. Você está recuperando o seu ID relacionada com a restrição após a primeira inserção e escrevê-lo de volta para os dados de segunda inserção antes de executar o comando?
  3. A restrição pode ser configurado errado no DB.

Você definitivamente não quer usar duas transações.

Parece que sua instrução de inserção para os Itens de Linha não está definindo corretamente o valor para a ordem .. este deve ser um resultado da etapa Insert order. Você já olhou (e testado) as instruções SQL individual?

Eu não acho que o problema tem nada a ver com controle de transação.

Eu não tenho experiência com isso, mas parece que você pode ter especificado um valor de chave que não está disponível na tabela pai. Desculpe, mas não posso ajudá-lo mais do que isso.

O problema é como você lida com o erro. Quando ocorre um erro, a transação não é revertida automaticamente para trás. Você certamente pode (e provavelmente deve) optar por fazer isso, mas dependendo do seu aplicativo ou de onde você é, você ainda pode querer cometê-lo. E, neste caso, é exatamente o que você está fazendo. Você precisa envolver algum erro código de manipulação em torno de lá para reverter seu código quando ocorre o erro.

Os olhares de erro como que os LineItems não estão sendo dada a devida FK OrderId que foi auto-gerada pelo a inserção da Ordem para a tabela Order. Você diz ter verificado as identificações, Você verificou as FKs nos detalhes da ordem, bem como?

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