Domanda

Non ho lavorato in SQL troppo a lungo, ma ho pensato ho capito che avvolgendo istruzioni SQL all'interno di una transazione, tutte le dichiarazioni completate, o nessuno di essi ha fatto. Qui è il mio problema. Ho un oggetto ordine che ha una collezione LineItem. Le voci sono correlate a order.OrderId. Ho verificato che tutti gli ID sono impostati e sono corretti , ma quando provo a salvare (inserto) l'ordine sto ottenendo L'istruzione INSERT in conflitto con l'estero KEY "FK_OrderItemDetail_Order". Il conflitto si è verificato nel database "MyData", tabella "dbo.Order", colonna 'OrderId'.

Codice pseudo:

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

codice vero e proprio:

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

Qualcuno ha suggerito che ho bisogno di usare due operazioni, una per l'ordine, e uno per le voci, ma sono ragionevolmente sicuri che è sbagliato. Ma ho combattuto questo per più di un giorno ora e ho bisogno di risolverlo in modo da poter andare avanti, anche se questo significa usare un cattivo lavoro in giro. Sto forse solo fare qualcosa di stupido?

È stato utile?

Soluzione

Ho notato che hai detto che stava utilizzando NetTiers per la generazione del codice.

Ho usato NetTiers me stesso e ho scoperto che se si elimina il vostro vincolo di chiave esterna dal vostro tavolo, aggiunge di nuovo allo stesso tavolo e quindi eseguire gli script di build per NetTiers di nuovo dopo aver apportato le modifiche nel database potrebbe aiutare azzerato il livello di accesso ai dati. Ho provato questo a volte con risultati positivi.

Buona fortuna con il tuo problema.

Altri suggerimenti

Senza vedere il codice, è difficile dire quale sia il problema. Potrebbe essere qualsiasi numero di cose, ma guarda questi:

  1. Questo è ovvio, ma i tuoi due comandi di inserimento sono sulla stessa connessione (ed il collegamento rimane aperto per tutto il tempo), che possiede la transazione giusta?
  2. Stai recuperando il proprio ID legati al vincolo dopo il primo inserimento e la scrittura di nuovo nei dati per secondo inserto prima di eseguire il comando?
  3. Il vincolo potrebbe essere istituito sbagliato nel DB.

È sicuramente non si vuole usare due operazioni.

Sembra che la sua dichiarazione di inserimento per i LineItems non è impostando correttamente il valore per l'ordine .. questo dovrebbe essere il risultato del passo Insert order. Hai guardato (e testato) l'individuo istruzioni SQL?

Non credo che il problema abbia a che fare con il controllo delle transazioni.

Non ho esperienza con questo, ma sembra che si potrebbe avere specificato un valore fondamentale che non è disponibile nella tabella padre. Ci dispiace, ma non posso aiutare più di questo.

Il problema è come gestire l'errore. Quando si verifica un errore, una transazione non viene automaticamente riavvolto. Si può certamente (e probabilmente dovrebbe) sceglie di farlo, ma a seconda della vostra applicazione o dove si è si può ancora voglia di commetterlo. E in questo caso, che è esattamente quello che stai facendo. È necessario avvolgere qualche errore di codice di gestione intorno lì per ritirare il codice quando si verifica l'errore.

L'errore sembra che i LineItems non viene data la giusta FK OrderId | che è stato generati automaticamente dal dell'inserto dell'Ordine al Tavolo Ordine. Tu dici che la verifica delle Ids, Hai controllato i FKS nei dettagli dell'ordine come bene?

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