Question

Je n'ai pas travaillé dans SQL trop longtemps, mais je pensais que je compris que les instructions SQL en enroulant dans une transaction, toutes les déclarations terminées, ou aucun d'entre eux ont fait. Voici mon problème. J'ai un objet de commande qui a une collection de LineItem. Les postes sont liés sur order.OrderId. J'ai vérifié que tous les Ids sont définis et sont corrects , mais lorsque je tente de sauver (insérer) l'ordre que je reçois L'instruction INSERT en conflit avec la politique étrangère KEY contrainte "FK_OrderItemDetail_Order". Le conflit a eu lieu dans la base de données "MyData", table "dbo.Order", colonne 'OrderId'.

Code psuedo:

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

code réel:

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

Quelqu'un a suggéré que je dois utiliser deux opérations, l'une pour l'ordre, et un pour les postes, mais je suis raisonnablement sûr que c'est faux. Mais je me bats contre cela depuis plus d'un jour maintenant et je dois le résoudre afin que je puisse passer à autre chose, même si cela signifie l'utilisation d'un mauvais travail autour. Est-ce que je fais peut-être juste quelque chose de stupide?

Était-ce utile?

La solution

J'ai remarqué que vous avez dit que vous utilisiez NetTiers pour votre génération de code.

Je l'ai utilisé NetTiers moi-même et ai trouvé que si vous supprimez votre clé étrangère de votre table, ajoutez à la même table, puis exécutez les scripts de compilation pour NetTiers à nouveau après avoir effectué vos modifications dans la base de données pourrait aider à réinitialiser la couche d'accès aux données. J'ai essayé ce à l'occasion avec des résultats positifs.

Bonne chance avec votre question.

Autres conseils

Sans voir votre code, il est difficile de dire quel est le problème. Il pourrait être un certain nombre de choses, mais regardez ceux-ci:

  1. Ceci est évident, mais vos deux commandes d'insertion sont sur la même connexion (et la connexion reste ouvert le temps entier) qui possède juste la transaction?
  2. Vous récupérez votre carte d'identité liée à la contrainte après la première insertion et l'écrire de nouveau dans les données pour le deuxième insert avant d'exécuter la commande?
  3. La contrainte pourrait être mis en place mal dans le DB.

Vous ne voulez pas utiliser deux transactions.

On dirait que votre déclaration d'insertion pour les LineItems ne sont pas correctement mise à la valeur de l'ordre .. cela devrait être le résultat de l'étape de Insert order. Avez-vous regardé (et testé) les instructions SQL individuelles?

Je ne pense pas que votre problème n'a rien à voir avec le contrôle des transactions.

Je n'ai aucune expérience avec cela, mais il semble que vous pourriez avoir spécifié une valeur clé qui ne figure pas dans la table parent. Désolé, mais je ne peux pas vous aider plus que cela.

Le problème est de savoir comment vous gérez l'erreur. Quand une erreur se produit, une transaction est pas automatiquement annulée. Vous pouvez certainement (et probablement devriez) choisir de le faire, mais en fonction de votre application ou si vous êtes vous voudrez peut-être encore de le commettre. Et dans ce cas, c'est exactement ce que vous faites. Vous avez besoin d'envelopper un code de gestion des erreurs autour de là pour rollback votre code lorsque l'erreur se produit.

L'erreur ressemble que les LineItems ne sont pas donnés dans le répertoire FK OrderId qui a été générée automatiquement par le l'insert de l'Ordre à la table Ordre. Vous dites que vous avez vérifié les Ids, Avez-vous vérifié les dans les détails FKs de commande aussi bien?

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