Καλώς ορίσατε στο dotNETZone.gr - Σύνδεση | Εγγραφή | Βοήθεια
σε

 

Αρχική σελίδα Ιστολόγια Συζητήσεις Εκθέσεις Φωτογραφιών Αρχειοθήκες

Display the IDENTITY from an Access to a DataGridView

Îåêßíçóå áðü ôï ìÝëïò Ηλίας Κεκάκος. Τελευταία δημοσίευση από το μέλος KelMan στις 05-03-2007, 01:07. Υπάρχουν 12 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  03-03-2007, 11:24 25803

    Display the IDENTITY from an Access to a DataGridView

    Συνημμένα: AccessIdentity.zip

      Γειά σας παιδιά,  ύστερα από 3 μέρες προσπάθειας και καθυστέρησης βρήκα τι εφταιγε και δεν μου επέστρεφε το SELECT @@IDENTITY to increment ORDERID πεδιο του πίνακα order της access που θα δείτε μέσα στο παράδειγμα. Το πρόβλημα ήταν ότι έκανα close το connection και μετά dispose. Τώρα αυτό που ψάχνω να βρώ είναι πώς θα το κάνω display στο DataGridView. Μπορεί κάποιος να μου πεί πως θα γίνει αυτό γιατί κοντεύω να τρελλαθώ. Επίσεις θα ήθελα να μου πείτε για τον κώδικα, πως σας φαίνετε, είναι καλός ή μπορεί να γίνει καλύτερος;

     

      Ευχαριστώ

  •  03-03-2007, 18:54 25819 σε απάντηση της 25803

    Απ: Display the IDENTITY from an Access to a DataGridView

    Στο query (db1.mdb) "usp_SelectOrders" έχεις δώσει στο OrderId, φίλτρο ίσο με μηδέν Smile


    while (!dead) learn();
  •  04-03-2007, 01:45 25826 σε απάντηση της 25819

    Απ: Display the IDENTITY from an Access to a DataGridView

    Συνημμένα: AccessIdentity1.zip

       Όχι δεν φταίει αυτό. Το πρόβλημα είναι στο update. Στο προηγούμενο παράδειγμα θέλω να ξεχωρίσω τις εγγραφές που γίνονται update, added or deleted. Αν κάνω update το dataadapter με το κανονικό dataset τότε το SELECT @@IDENTITY μου επιστρέφει το πραγματικό OrderID (δες το παράδειγμα που σου στέλνω). Οι ερωτήσεις παραμένουν: 1. Υπάρχει τρόπος να βρώ πόσες εγγραφές έγιναν update, added or deleted; 2. Ο κώδικας είναι καλός ήμπορει να γίνει καλύτερος;

     

      Ευχαριστώ.

  •  04-03-2007, 06:38 25835 σε απάντηση της 25826

    Απ: Display the IDENTITY from an Access to a DataGridView

    Χρησιμοποίησε την GetChanges.

     

    Πχ: Dim ChangesDataSet As DataSet = DataSetOrders.GetChanges()

     


    while (!dead) learn();
  •  04-03-2007, 09:07 25836 σε απάντηση της 25835

    Απ: Display the IDENTITY from an Access to a DataGridView

      Καλημέρα Γιώργο, αν δεις αυτό χρησιμοποιώ στο παράδειγμα που έχω στο 1ο post, αλλά σε αυτή την περίπτωση δεν λαμβάνω το IDENTITY. Για να λάβω το IDENTITY πρέπει να χρησιμοποιήσω το original dataset όπως στο παράδειγμα του 2ου post.
  •  04-03-2007, 17:16 25858 σε απάντηση της 25836

    Απ: Display the IDENTITY from an Access to a DataGridView

    Γιατί θες να ξεχωρίσεις τις εγγραφές που γίνονται update, added or deleted;


    while (!dead) learn();
  •  04-03-2007, 19:10 25863 σε απάντηση της 25858

    Απ: Display the IDENTITY from an Access to a DataGridView

      Τις ξεχώριζα έτσι όπως είναι στο παράδειγμα του 1ου post μου και στο παρακάτω παράδειγμα:

    Dim dataSetChanged As DataSet = DataSetOrders.GetChanges(DataRowState.Modified)

    If Not dataSetChanged Is Nothing Then

    m_daOrders.Update(dataSetChanged, "Orders")

    End If

    Dim dataSetDeleted As DataSet = DataSetOrders.GetChanges(DataRowState.Deleted)

    If Not dataSetDeleted Is Nothing Then

    m_daOrders.Update(dataSetDeleted, "Orders")

    End If

    Dim dataSetAdded As DataSet = DataSetOrders.GetChanges(DataRowState.Added)

    If Not dataSetAdded Is Nothing Then

    m_daOrders.Update(dataSetAdded.Tables("Orders"))

    End If

      Αν χρησιμοποιήσω αυτόν τον κώδικα τότε δεν λειτουργεί ό παρακάτω κώδικας:

    Dim cmdGetIdentity As OleDb.OleDbCommand = New OleDb.OleDbCommand("SELECT @@IDENTITY", oOrders.Connection1)

    If e.Status = UpdateStatus.Continue AndAlso e.StatementType = StatementType.Insert Then

    ' Get the Identity column value

    e.Row("OrderID") = Int32.Parse(cmdGetIdentity.ExecuteScalar().ToString())

    e.Row.AcceptChanges()

    End If

      Για να δουλέψει ο κώδικας του GET IDENTITY θα πρέπει να χρησιμοποιήσω τον εξής κώδικα:

    m_daOrders.Update(DataSetOrders.Tables("Orders"))

      Αρα οι ερωτήσεις μου στο πιο πάνω post παραμένουν.

  •  04-03-2007, 19:23 25865 σε απάντηση της 25863

    Απ: Display the IDENTITY from an Access to a DataGridView

    Είναι γενικότερα λανθασμένη η υλοποίηση που κάνεις. Δεν είναι σωστό να τραβάς σκέτo το @@IDENTITY γιατί δεν υπάρχει εγγύηση ότι αυτό που διαβάζεις βρίσκεται πραγματικά μέσα στη βάση ούτε ότι έχει προέλθει από συγκεκριμένο πίνακα. Απλά βασίζεσαι στην υπόθεση ότι επειδή τρέχουν τα δύο statements πολύ γρήγορα το ένα μετά το άλλο, παίρνεις το σωστό identity. Ο σωστός τρόπος είναι να ορίσεις στο Insert Command, το INSERT statement να συνοδεύεται από το SELECT @@Identity. Δες εδώ για περισσότερα: http://www.dotnetzone.gr/cs/forums/thread/8893.aspx


    Vir prudens non contra ventum mingit
  •  04-03-2007, 19:57 25868 σε απάντηση της 25865

    Απ: Display the IDENTITY from an Access to a DataGridView

      Γειά σου Μάνο, αυτό το έχω δει στο 3ήμερο που είχα το πρόβλημα και προσπαθούσα να βρώ την λύση του. Αλλά η ΒΔ που χρησιμοποιώ είναι Access και νομίζω ότι δεν ισχύει αυτή η λύση. Δεν ξέρω αν υπάρχει αλλη λύση για την Access.

     

      Thanks

  •  04-03-2007, 21:04 25872 σε απάντηση της 25868

    Απ: Display the IDENTITY from an Access to a DataGridView

    Δεν μου απάντησες γιατί θες να ξεχωρίσεις τις εγγραφές που γίνονται update, added or deleted;


    while (!dead) learn();
  •  04-03-2007, 21:31 25874 σε απάντηση της 25868

    Απ: Display the IDENTITY from an Access to a DataGridView

    Ουυυπππςςςς!!! Τύφλα μου! Access είπες ε;

    Στην Access δεν γίνεται αυτό που λέω γιατί για να μπορέσεις να βάλεις "INSERT ... ; SELECT ..." θα πρέπει η βάση να υποστηρίζει batch queries. Οπότε η λύση είναι η εξής:

    Αρχικά δηλώνεις το refresh command:

    Dim cmdRefresh As OleDb.OleDbCommand

    και μέσα στον constructor:

    cmdRefresh = New OleDb.OleDbCommand("SELECT @@IDENTITY", Connection)

    Τώρα, το μόνο που μένει είναι να τρέχεις το refresh command κάθε φορά που γίνεται insert μια εγγραφή. Για να το κάνεις αυτό θα εκμεταλλευτείς το RowUpdated event του DataAdapter object. Έτσι, στο Form1_Load εκεί που δημιουργείς τον  m_daOrders DataAdapter, θα γράψεις από κάτω:

    AddHandler m_daOrders.RowUpdated, AddressOf RowUpdatedHandler

    Τέλος, σου χρειάζεται η ρουτίνα που θα τρέχει σε κάθε update:

    Private Sub RowUpdatedHandler(ByVal sender As Object, ByVal e As OleDb.OleDbRowUpdatedEventArgs)
      If e.Status = UpdateStatus.[Continue] AndAlso (e.StatementType = StatementType.Insert) Then
        e.Row("ID") = CInt(cmdRefresh.ExecuteScalar)
        e.Row.AcceptChanges()
      End If
    End Sub

    Από εκεί και πέρα, μπορείς να το ραφινάρεις λίγο και να βάλεις το DAL να σου γυρίζει το refresh command, κλπ.


    Vir prudens non contra ventum mingit
  •  04-03-2007, 23:41 25884 σε απάντηση της 25874

    Απ: Display the IDENTITY from an Access to a DataGridView

      Γιώργο, άν κάνω αυτό που λες τότε αυτό που γράφει ο Μάνος δεν λειτουργεί. Μάνο αυτό το υλοποίησα στο 1ο παράδειγμα και δεν δουλεύει. Μόνο έτσι όπως κάνω update στο 2ο παράδειγμα δουλεύει. Εκτός και αν δεν καταλαβαίνω κάτι.
  •  05-03-2007, 01:07 25887 σε απάντηση της 25884

    Απ: Display the IDENTITY from an Access to a DataGridView

    Η πρώτη σου προσπάθεια δεν δουλεύει για άλλον λόγο. Η τεχνική του RowUpdated event παίζει μια χαρά, αλλού είναι το πρόβλημα.

    Όταν σπας το DataSet σε τρία (dataSetChanged, dataSetDeleted, dataSetAdded) και τρέχει η RowUpdated, τότε το 

          e.Row("OrderID") = Int32.Parse(cmdGetIdentity.ExecuteScalar())

    διαβάζει το @@IDENTITY αλλά αυτό πέφτει μέσα στην αντίστοιχη εγγραφή του πίνακα Orders που βρίσκεται στο dataSetAdded DataSet. Έτσι, η τιμή δεν εμφανίζεται ποτέ μέσα στον πίνακα που είναι binded στο DataGridView κι εσύ βλέπεις (DataSetOrders.Tables("Orders")). Θα το διαπιστώσεις, αν αντί

          m_daOrders.Update(dataSetAdded.Tables("Orders"))

    κάνεις

          m_daOrders.Update(DataSetOrders.Tables("Orders"))

    Έτσι λοιπόν, η ButtonUpdate_Click γίνεται

    Private Sub ButtonUpdate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonUpdate.Click
    AddHandler m_daOrders.RowUpdated, AddressOf HandleRowUpdated
       Try
          DumpTableContents("Before", DataSetOrders.Tables("Orders"))
          m_daOrders.Update(DataSetOrders.Tables("Orders"))
          DumpTableContents("After", DataSetOrders.Tables("Orders"))
       Catch ex As Exception
          Debug.WriteLine(ex.Message)
       End Try
    End Sub

    Η DumpTableContnets χρησιμεύει για να δεις τα περιεχόμενα του πίνακα ώστε να διαπιστώσεις ότι πραγματικά έχουν τις τιμές που περιμένεις

    Sub DumpTableContents(ByVal text As String, ByVal dtWorking As DataTable)
       Debug.WriteLine(text)
       For Each r As DataRow In dtWorking.Rows
          For i As Integer = 0 To r.ItemArray.Length - 1
             Debug.Write(String.Format("{0},", r(i)))
          Next
          Debug.WriteLine()
       Next
    End Sub

    Ουσιαστικά, το πρόβλημά σου ήταν θέμα debugging ώστε να καταλάβεις που ακριβώς οφείλεται το λάθος. Στην προκειμένη περίπτωση, όταν κάνεις GetChanges ώστε να πάρεις τα DataRows από ένα DataSet/DataTable και να τα ρίξεις σε άλλο, δεν κάνεις copy τα reference αλλά δημιουργείς νέα objects.


    Vir prudens non contra ventum mingit
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems