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

 

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

Αντιγραφή ενός DataRow σε ένα νέο μέσα το ίδιο πίνακα

Îåêßíçóå áðü ôï ìÝëïò γιωργος μπακογιαννης. Τελευταία δημοσίευση από το μέλος γιωργος μπακογιαννης στις 27-08-2006, 09:38. Υπάρχουν 8 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  01-07-2006, 09:39 14357

    Wink [;)] Αντιγραφή ενός DataRow σε ένα νέο μέσα το ίδιο πίνακα



        ''' <summary>
        ''' Αντιγραφή ενός DataRow σε ένα νέο μέσα το ίδιο πίνακα (Προϋπόθεση είναι το DataTable να έχει ID και να είναι AutoIncrement)
        ''' </summary>
        ''' <param name="dt">Δίνουμε το DataTable</param>
        ''' <param name="dr">Δίνουμε το DataRow που θέλουμε να αντιγράψουμε</param>
        ''' <remarks>Usage: DataRowClone(TableNameΧΧΧ, dr)</remarks>
        Public Sub DataRowClone(ByVal dt As Data.DataTable, ByVal dr As Data.DataRow)
            Dim intNewId As Integer, drNew() As Object = dr.ItemArray
            For Each col As Data.DataColumn In dt.Columns
                If Not col.AutoIncrement Then Continue For
                For Each drX As Data.DataRow In dt.Rows
                    If CInt(drX(col.Ordinal)) < intNewId Then intNewId = CInt(drX(col.Ordinal))
                Next
                drNew(col.Ordinal) = intNewId - 1
                Exit For
            Next
            dt.Rows.Add(drNew)
        End Sub

     


    while (!dead) learn();
  •  03-07-2006, 19:16 14381 σε απάντηση της 14357

    Απ: Αντιγραφή ενός DataRow σε ένα νέο μέσα το ίδιο πίνακα

    • Δεν είναι ακριβώς αντιγραφή γιατί δεν διατηρεί το RowState αν αυτό είναι διάφορο του added καθώς επίσης και το original version αν είναι modified
    • Δεν ξέρουμε ότι το drX(col.Ordinal) μπορεί να γυρίσει πάντα σε integer
    • Εκτός από τις AutoIncrement, υπάρχουν και οι IsReadOnly κολώνες
    • Αν το δουλεύαμε με dt.ImportRow(dr), δεν θα ήταν πιο απλό;

     


    Χρήστος Γεωργακόπουλος
  •  03-07-2006, 19:46 14382 σε απάντηση της 14381

    Απ: Αντιγραφή ενός DataRow σε ένα νέο μέσα το ίδιο πίνακα

     

    "Αν το δουλεύαμε με dt.ImportRow(dr), δεν θα ήταν πιο απλό;"

     

     

    Το dt.ImportRow(dr) μου κάνει ακριβώς το DataRow Import άρα παίρνω πχ:

     

    System.Data.ConstraintException: Column 'InterestRateId' is constrained to be unique.  Value '3' is already present.


    Άρα θα το μετατρέψω σε ερώτηση: Πώς θα μπορέσω να κάνω αντιγραφή ενός DataRow σε ένα νέο μέσα το ίδιο πίνακα; (Γιατί πραγματικά δεν μπόρεσα να βρω κάτι)


    while (!dead) learn();
  •  03-07-2006, 20:14 14383 σε απάντηση της 14382

    Απ: Αντιγραφή ενός DataRow σε ένα νέο μέσα το ίδιο πίνακα

    Οι μοναδικές λύσεις είναι το ImportRow καθώς και το να κάνεις Select πάνω στο DataTable ώστε να πάρεις ένα copy από το Row. Με αυτούς τους τρόπους δεν έχεις πρόβλημα με τα versions του DataRow. Από εκεί και πέρα, ανάλογα με το schema της βάσης, πρέπει να αλλάξεις ό,τι row values μπορεί να κάνουν conflict (primary keys, read-only fields, etc). Θες να γράψεις τόσο generic κώδικα ώστε να παίζει ανεξάρτητα από το schema? Χλωμό το βλέπω...


    Vir prudens non contra ventum mingit
  •  03-07-2006, 20:22 14384 σε απάντηση της 14383

    Απ: Αντιγραφή ενός DataRow σε ένα νέο μέσα το ίδιο πίνακα

    To DataTable να έχει Id (int32 ή int64) και να είναι AutoIncrement.

    Άρα copy όλα τα πεδία ένα προς ένα, με Id την πρώτη φορά -1, μετά -2 κτλ.

    Αυτό είναι εφικτό;


    while (!dead) learn();
  •  03-07-2006, 21:52 14386 σε απάντηση της 14382

    Απ: Αντιγραφή ενός DataRow σε ένα νέο μέσα το ίδιο πίνακα

    Γιώργο δοκίμασε και το παρακάτω

    Dim dt As DataTable

    Dim drNew As DataRow

    dt = dtOldTable.Clone

    drNew = dtOldTable.Rows(0)

    dt.ImportRow(drNew)

    sorry δε μπορώ να επεκταθώ λόγω έλλειψης χρόνου


    Βαγγέλης Ξανθάκης
    Independent Consultant
    www.aylos.com
  •  03-07-2006, 22:06 14388 σε απάντηση της 14386

    Απ: Αντιγραφή ενός DataRow σε ένα νέο μέσα το ίδιο πίνακα

    Φίλε Βαγγέλη ένα πίνακα θέλω να έχω
    while (!dead) learn();
  •  03-07-2006, 23:57 14390 σε απάντηση της 14388

    Απ: Αντιγραφή ενός DataRow σε ένα νέο μέσα το ίδιο πίνακα

    Δεν χρειάζεται να κάνεις clone ολόκληρο το DataTable για να πάρεις το DataRow που σε ενδιαφέρει, μπορείς να το κάνεις με το Select method του DataTable. το θέμα είναι τι γίνεται μετά καθώς αν επιχειρήσεις να προσθέσεις το DataRow με το ImportRow θα χτυπήσει το primary key column. Επιπρόσθετα, αν το primary key column είναι auto increment τότε δεν μπορείς να το αλλάξεις γιατί είναι read only. Θα το σκεφτώ λίγο ακόμα αλλά έχω την εντύπωση ότι τελικά ή θα κάνεις copy τα values από τα DataColumns μέσω του ItemArray (όπως στη λύση σου Γιώργο) ή θα πρέπει να είναι τέτοιο το schema που να επιτρέπεται το ImportRow.
    Vir prudens non contra ventum mingit
  •  27-08-2006, 09:38 15980 σε απάντηση της 14357

    Απ: Αντιγραφή ενός DataRow σε ένα νέο μέσα το ίδιο πίνακα

    Μιας και όλο τον Αύγουστο έγραψα από την αρχή ότι είχα σε VB.Net 2005 σε C# 2005, παραθέτω και την «DataRowClone» και σε C#.

     

    Και περνάει χωρίς λάθη τους ελέγχους του «Microsoft FxCop 1.35»

     

    VB.Net sorry :(

     

    Καλό χειμώνα σε όλους.

     

                    /// <summary>
            /// Αντιγραφή ενός DataRow σε ένα νέο μέσα το ίδιο πίνακα (Προϋπόθεση είναι το dataTable να έχει (int)Id και να είναι AutoIncrement)
            /// </summary>
            /// <param name="dataTable">Δίνουμε το DataTable</param>
            /// <param name="dataRow">Δίνουμε το DataRow που θέλουμε να αντιγράψουμε</param>
            /// <remarks>Usage: DataRowClone(tableName, dataRow)</remarks>
            /// <returns>Επιστρέφει το νέο DataRow</returns>
            public static DataRow Clone(DataTable dataTable, DataRow dataRow) {
                if (dataTable == null || dataRow == null) return null;
                int newId = 0, position = dataTable.Rows.Count;
                object[] newDataRow = dataRow.ItemArray;
                foreach (DataColumn dc in dataTable.Columns) {
                    if (!dc.AutoIncrement) continue;
                    foreach (DataRow dr in dataTable.Rows) {
                        if ((int)(dr[dc.Ordinal]) < newId) newId = (int)(dr[dc.Ordinal]);
                    }
                    newDataRow[dc.Ordinal] = newId - 1;
                    break;
                }
                dataTable.Rows.Add(newDataRow);
                return dataTable.Rows[position];
            }
        }


    while (!dead) learn();
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems