Domanda

Sono utilizzando dataset ADO.NET nelle mie applicazioni VB. Ho un DataSet tipizzato con tavolo Genitore unico e molte tabelle figlio. Voglio generare chiave di identità quando inserisco i dati in tabella padre e quindi aggiornare i dati in tutte le tabelle figlio con la stessa chiave (come la chiave Foregin).

Finalmente, voglio aggiornare il set di dati nel database (SQL Server08).

Bene, la cosa di cui sopra può essere possibile inserendo prima tabella padre nel database direttamente, ottenere la colonna di identità e di utilizzare per per le tabelle del bambino.

Ma io voglio questo come un funzionamento automatico (come LINQ to SQL, che si prende cura di primario e chiave esterna nella DataContext.)

I tale cosa possibile nel set di dati che si prende cura della colonna Autogenerated per tabelle padre e figlio?

Grazie,

ABB

Nessuna soluzione corretta

Altri suggerimenti

Credo che questo dovrebbe essere più evidente e dovrebbe funzionare senza alcun ritocco. Ma ancora, è abbastanza facile.

La soluzione ha due parti:

  1. Crea DataRelation tra tabelle figlio e genitore e impostarlo a cascata su aggiornamenti. In questo modo ogni volta che cambia genitore Id, tutti i bambini verranno aggiornate.

    Dim rel = ds.Relations.Add(parentTab.Columns("Id"), childTab.Columns("ParentId"))
    rel.ChildKeyConstraint.UpdateRule = Rule.Cascade
    
  2. comandi di inserimento Dataset e aggiornamento sono due vie: Se sono presenti parametri di uscita rilegati o le righe di dati restituiti, saranno utilizzati per aggiornare la riga di dati che ha causato l'aggiornamento.

    Questo è molto utile per questo particolare problema: ottenere le colonne generate automaticamente tornare alla applicazione. A parte dell'identità questo potrebbe essere per esempio una colonna timestamp. Ma l'identità è più utile.

    Tutto quello che dobbiamo fare è impostare comando Inserisci per tornare identità. Ci sono diversi modi per farlo, ad esempio:

    a) Utilizzo di stored procedure con parametri di uscita. Questo è il modo più portatile tra banche dati "reali".

    b) Uso di più istruzioni SQL, con ultimo rinvio riga inserita. Questo è quanto ne so specifico di SQL Server, ma la più semplice:

    insert into Parent (Col1, Col2, ...) values (@Col1, @Col2, ...);
    select * from Parent where Id = SCOPE_IDENTITY();
    

Dopo aver impostato questa funzione, tutto quello che dovete fare è creare righe padre con Ids che sono unici (entro singolo set di dati), ma impossibile nel database. I numeri negativi sono di solito una buona scelta. Poi, quando si salvano le modifiche del set di dati al database, tutte le nuove righe padre otterrà Ids reali dal database.


Nota: Se vi capita di lavorare con database senza supporti multipli dichiarazioni e senza le stored procedure (ad esempio Access), è necessario gestore di eventi setup su evento RowUpdated adattatore tabella padre. Nella hanler è necessario per ottenere l'identità con il comando select @@IDENTITY.


Alcuni link:

Un paio di cose da sottolineare.

  1. Sì, è sicuramente bisogno di relazioni assegnate per entrambe le tabelle. È possibile controllare da editor di XSD (doppio clic sul file XSD). Per default la relazione è impostato come 'unica relazione' che non ha alcun 'regola di aggiornamento'. Modifica questo rapporto andando in 'Modifica relazione' e selezionare 'Foreign Key Vincolo solo' o 'Entrambi ~~~' uno. E la necessità di impostare 'Aggiorna Rule' come Cascade! 'Elimina regola' sta a voi.

  2. Ora, quando si utilizza ID di un nuovo riga della tabella padre (AutoIncrement) per le nuove righe della tabella figlio come una chiave esterna, si deve aggiungere la riga padre nella tabella prima prima di utilizzare ID della nuova riga padre intorno.

  3. Non appena si chiama aggiornamento per la tabella padre utilizzando TableAdapter, nuove righe della tabella figlio associati avranno corretto parentID AUTOMATICAMENTE.

I miei semplici frammenti di codice:

'--- Make Parent Row
Dim drOrder as TOrderRow = myDS.TOder.NewTOrderRow
drOrder.SomeValue = "SomeValue"
myDS.TOrder.AddTOrderRow(drOrder) '===> THIS SHOULD BE DONE BEFORE CHILD ROWS

'--- Now Add Child Rows!!! there are multiple ways to add a row into tables....
myDS.TOrderDetail.AddTOrderDetailRow(drOrder, "detailValue1")
myDS.TOrderDetail.AddTOrderDetailRow(drOrder, "detailvalue2")
'....
'....

'--- Update Parent table first
myTableAdapterTOrder.Update(myDS.TOrder)
'--- As soon as you run this Update above for parent, the new parent row's AutoID(-1)
'--- will become real number given by SQL server. And also new rows in child table will
'--- have the updated parentID

'--- Now update child table
myTableAdapterTOrderDetail.Update(myDS.TOrderDetail)

Spero che aiuta!

E se non si desidera utilizzare i set di dati e tuttavia ottenere gli ID assegnati al bambino e ottenere gli ID in modo da poter aggiornare il modello: https://danielwertheim.wordpress.com/2010/10/ 24 / C-batch identità-inserti /

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