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

 

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

Custom Update Command

Îåêßíçóå áðü ôï ìÝëïò evliatsas. Τελευταία δημοσίευση από το μέλος KelMan στις 10-07-2006, 09:17. Υπάρχουν 9 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  08-07-2006, 12:13 14525

    Custom Update Command

    Το πρόβλημα είναι το εξής....

    Έχω σε μία Windows Form (VS 2005), δύο Views από SQL Server Express 2005. Τα Views αυτά είναι Related σε ένα απλό μοντέλο Customer->Products.

    Όσο το μόνο που έχω να κάνω, είναι να τα παρουσιάζω δομημένα, όλα ωραία και μάλιστα πιο εύκολα και αυτοματοποιημένα από την προηγούμενη έκδοση του VS.

    Έλα όμως που θέλω ο χρήστης να κάνει Edit ένα πεδίο Discount για κάθε πελάτη!!! και μάλιστα ο απαιτητικός θέλω αυτό να αποθηκεύεται στον αντίστοιχο πίνακα στην βάση!!!

    Λογικά λοιπόν σκεπτόμενος, πήγα να γράψω ένα SQL Command το οποίο θα εκτελεστεί στο Open Connection που έχω στη βάση.

    Παρότι όμως έχω χρησιμοποιήσει την πρακτική αυτή δεκάδες φορές στο VS 2003, έχω δύο μέρες που το καινούριο Studio και οι DataBinding "ευκολίες" του με κάνουν να αισθάνομαι πραγματικά ηλίθιος.

    Παιδιά, όποιος έχει κάποια λύση, please put me out of my misery.

    Σημείωση: Οι πίνακες έιναι τρείς (κλασική σχέση n:n) και βέβαια το Discount πεδίο βρίσκεται στον ενδιάμεσο πίνακα, τα views τα ΄"σηκώνω" σε Infragistics Grid το οποίο προβάλει σε nested μορφή related records.

  •  08-07-2006, 17:24 14530 σε απάντηση της 14525

    Απ: Custom Update Command

    αν μπορείς εξήγησε ποιο είναι το πρόβλημα; Δεν μπορείς να πάρεις από το UI την σωστή τιμή, έχεις πρόβλημα με το open connection, το update command κλπ;

    Ποια ακριβώς component χρησιμοποιείς.
    Dimitris Papadimitriou
    Software Development Professional
    dotNETZone.gr News

    Οι απαντήσεις παρέχονται για συγκεκριμένες ερωτήσεις και χωρίς καμιά εγγύηση. Διαβάστε επίσης τους όρους χρήσης.
  •  09-07-2006, 00:40 14541 σε απάντηση της 14530

    Απ: Custom Update Command

    Συγνώμη για τα κενά της ερώτησης.

    Το Component που χρησιμοποιώ είναι το UltraWinGrid v6.1

    Το connection για κάποιο (άγνωστο σε μένα) λόγο δεν είναι open αλλά προσπέρασα τον ύφαλο με

    System.Data.SqlClient.SqlConnection sqlconn = new System.Data.SqlClient.SqlConnection();
                sqlconn.ConnectionString =MyApp.Properties.Settings.Default.MyAppDataConnectionString;
                sqlconn.Open();

     

    Μετά προσπάθησα να δημιουργήσω μία Custom Update() Function στο κατάλληλο TableAdapter του DataSet, μιάς και δεν γίνεται Auto Generated λόγω του JOIN που περιέχει το Select Statement. Δυστυχώς μετά από αρκετές προσπάθειες δεν τα κατάφερα :(

    Έπειτα δοκίμασα έναν ποιο ευθύ και προγραμματιστικά "μή έξυπνο" τρόπο (πιο πολύ για να τεστάρω άν δουλεύει)



    foreach (DataRow dr in this.MyAppDataSet.Tables[0].Rows)
                {               
                    string updateCommand = "Update [dbo].[nCustomers_nProducts] SET [discount]="+dr.ItemArray[0].ToString()+ " WHERE [customer_id]="+dr.ItemArray[5].ToString()+" and [product_id]="+dr.ItemArray[1].ToString();
                    System.Data.SqlClient.SqlCommand sqlcomm = new System.Data.SqlClient.SqlCommand();
                    sqlcomm.CommandText = updateCommand;
                    sqlcomm.Connection= sqlconn;
                    sqlcomm.ExecuteNonQuery();
                }

    Εδώ, άν και το updateCommand string που παράγεται παίζει κανονικά μέσα από τον SQL Server Manager, το executable ρίχνει exception στο ExecuteNonQuery().

    Να σημειώσω πως το PK του πίνακα nCustomers_nProducts είναι ο συνδιασμός των πεδίων customer_id και product_id και επίσης πως το DataSet Table παίρνει τις αλλαγές των τιμών από το UI Component.

    Τέλος αυτό που με απογοήτευσε τελείως είναι πως δεν μπόρεσα να βρώ πουθενά ένα παράδειγμα για το παραπάνω (κοινό πιστεύω) σενάριο.

    Ο μόνος τρόπος που το κατάφερα να δουλεύει, είναι άν δεν εκτελέσω JOIN στο Select, αλλά τότε ο χρήστης δεν βλέπει το λεκτικό των πεδίων, αλλά το smallint που χρησιμοποιώ ώς id.

  •  09-07-2006, 01:19 14542 σε απάντηση της 14541

    Απ: Custom Update Command

    Εγώ στο UltraWinGrid δουλεύω λίγο διαφορετικά. Φτιάχνω το dataset κανονικά, ορίζοντας τα DataTables και καθορίζοντας τις σχέσεις μεταξύ τους, χωρίς δηλαδή να φτιάχνω queries με joins, εφόσον βέβαια πρόκειται να κάνω updates. Κατόπιν, ρίχνω το UltraWinGrid στη φόρμα. Επίσης, για κάθε Column που θέλω να κάνει lookup βάζω κι από ένα UltraDropDown και το συνδέω ανάλογα στο ValueList property του αντίστοιχου column του UltraWinGrid.


    Vir prudens non contra ventum mingit
  •  09-07-2006, 11:52 14547 σε απάντηση της 14541

    Απ: Custom Update Command

     evliatsas wrote:

    Μετά προσπάθησα να δημιουργήσω μία Custom Update() Function στο κατάλληλο TableAdapter του DataSet, μιάς και δεν γίνεται Auto Generated λόγω του JOIN που περιέχει το Select Statement. Δυστυχώς μετά από αρκετές προσπάθειες δεν τα κατάφερα :(

    Δεν μπορώ να πω κάτι γιατί δεν αναφέρεις τι έγινε τελικά

     evliatsas wrote:

    Εδώ, άν και το updateCommand string που παράγεται παίζει κανονικά μέσα από τον SQL Server Manager, το executable ρίχνει exception στο ExecuteNonQuery().

    Το query σου φαίνεται σωστό. Ποιο είναι το exception που παίρνεις;

    Σχετικά με τον τρόπο που προτείναι ο KelMain και εγώ κάτι τέτοιο κάνω. Μόνο που αν το πεδίο που θέλουμε να αντικαταστήσουμε είναι ένα πεδίο τύπου customerId, δεν μπορούμε να φορτώσουμε όλο τον πίνακα customer, μια που αυτός αναμένεται να είναι μεγάλος.


    Dimitris Papadimitriou
    Software Development Professional
    dotNETZone.gr News

    Οι απαντήσεις παρέχονται για συγκεκριμένες ερωτήσεις και χωρίς καμιά εγγύηση. Διαβάστε επίσης τους όρους χρήσης.
  •  09-07-2006, 12:48 14549 σε απάντηση της 14547

    Απ: Custom Update Command

    Το Exception που παίρνω είναι:

    System.Data.SqlClient.SqlException was unhandled
      Message="Incorrect syntax near '0000'."
      Source=".Net SqlClient Data Provider"
      ErrorCode=-2146232060

     

    Όσο αφορά την Update() Function, ακολούθησα την πεπατημένη(δεξί κλίκ στο TableAdapter, AddQuery..,Use SQL Statement, Update.....) και έκανα generate την Update(int @Param1,int @Param2,double @Parma3).Όταν όμως την καλούσα έπαιρνα exception για duplicate keys και την προτροπή relax constraints.

    Θα προσπαθήσω να τα καταφέρω χρησιμοποιώντας ValueList.

  •  09-07-2006, 14:07 14551 σε απάντηση της 14549

    Απ: Custom Update Command

    Η λύση με τα ValueLists δούλεψε κανονικά



    Infragistics.Win.ValueList myCustomerList = new Infragistics.Win.ValueList();
    foreach (DataRow dr in this.MyAppDataDataSet.Tables["Customers"].Rows)
                {
                    myCustomerList .ValueListItems.Add(dr.ItemArray[0], dr.ItemArray[1].ToString());
                }
    myUltraGrid.DisplayLayout.Bands[0].Columns["customerID"].ValueList = myCustomerList ;

     

    Οπότε μετά με nCustomers_nProductsTableAdapter.Update(MyAppDataDataSet) καθαρίζω.

    Thanks a lot guys....

    Βέβαια η αρχική μου απορία, για το πως μπορώ να κατασκευάσω εγώ ένα Update Query παραμένει, οπότε άν και θα σημειώσω το thred επιλυμένο, παρακαλείται όποιος βρεί κάποιο σχετικό παράδειγμα να το κάνει post.

  •  09-07-2006, 17:07 14554 σε απάντηση της 14551

    Απ: Custom Update Command

     evliatsas wrote:



                    myCustomerList .ValueListItems.Add(dr.ItemArray[0], dr.ItemArray[1].ToString());

    Γενικά δεν είναι καλό να χρησιμοποιείς το ItemArray δίνοντας index για να πάρεις την τιμή μιας στήλης. Προτίμησε να πάρεις την τιμή με dr["columnName"]


    Dimitris Papadimitriou
    Software Development Professional
    dotNETZone.gr News

    Οι απαντήσεις παρέχονται για συγκεκριμένες ερωτήσεις και χωρίς καμιά εγγύηση. Διαβάστε επίσης τους όρους χρήσης.
  •  09-07-2006, 20:57 14556 σε απάντηση της 14554

    Απ: Custom Update Command

     papadi wrote:

    Γενικά δεν είναι καλό να χρησιμοποιείς το ItemArray δίνοντας index για να πάρεις την τιμή μιας στήλης. Προτίμησε να πάρεις την τιμή με dr["columnName"]

     

    Έχεις απόλυτο δίκιο, και μάλιστα συνάντησα πρόβλημα αμέσως και αναγκάστηκα εκ των πραγμάτων να ακολουθήσω την λύση που προτείνεις.

    Ευχαριστώ και πάλι....

     

  •  10-07-2006, 09:17 14559 σε απάντηση της 14556

    Απ: Custom Update Command

    H κάθε μέθοδος έχει τα πλεονεκτήματα και μειονεκτήματά της.

    Αν χρησιμοποιούμε το column name (ως string) είναι καλό γιατί διαβάζεται εύκολα ο κώδικας και σε προστατεύει αν στην πορεία της ανάπτυξης αλλάξεις το query προσθέτοντας ή αφαιρώντας πεδία. Από την άλλη μεριά όμως κάθε φορά που συναντά ως παράμετρο το string θα πρέπει να ψάξει στην εσωτερική δομή του να βρει σε ποιό index αντιστοιχεί αυτό το string, που σημαίνει ότι χάνουμε στο performance. Επίσης χάνουμε σε type safety καθώς ένα τυπογραφικό λάθος στο string θα φανεί μόνο κατά το runtime. Από την άλλη μεριά, αν χρησιμοποιήσουμε indexes αντιστρέφονται τα πλεονεκτήματα και τα μειονεκτήματα.

    Όταν χρησιμοποιούμε DataSets, η μόνη λύση για να ξεπεράσουμε τα μειονεκτήματα είναι να φτιάξουμε Typed DataSet. Κατά τ'άλλα, προσωπικά προτιμώ το string μόνο και μόνο για το readability του κώδικα.

    Ωστόσο αν χρησιμοποιούμε DataReader υπάρχει και μια τρίτη μέθοδος που έχει μόνο πλεονεκτήματα Smile

    Το object model του ADO.NET προσφέρει τη μέθοδο GetOrdinal. Δείτε αυτό το snippet (από MSDN):

      Dim mySelectQuery As String = "SELECT OrderID, CustomerID FROM Orders"
      Dim myConnection As New SqlConnection(myConnString)
      Dim myCommand As New SqlCommand(mySelectQuery, myConnection)
      myConnection.Open()
      Dim myReader As SqlDataReader = myCommand.ExecuteReader()
      Dim custIdCol As Integer = myReader.GetOrdinal("CustomerID")
      Do While myReader.Read()
        Console.WriteLine("CustomerID = {0}", myReader.GetString(custIdCol))
      Loop
      myReader.Close()
      myConnection.Close()

    Παρατηρήστε το myReader.GetOrdinal("CustomerID"). Είναι το μόνο σημείο ελέγχου για πιθανό λάθος σύμφωνα με αυτά που λέγαμε προηγουμένως. Επίσης, άλλο ένα best practice είναι το type specific Get method, όπως εδώ το GetString. Υποθέτω όλα αυτά υπάρχουν στον DataReader προκειμένου να μπορεί να πετύχει κανείς το μέγιστο performance μιας που στην ουσία είναι ένας firehose cursor.

     


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