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

 

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

Object reference not set to an instance of an object.

Îåêßíçóå áðü ôï ìÝëïò thanosk. Τελευταία δημοσίευση από το μέλος Adamantios στις 09-01-2008, 15:21. Υπάρχουν 8 απαντήσεις.
Ταξινόμηση Δημοσιεύσεων: Προηγούμενο Επόμενο
  •  08-01-2008, 19:11 38960

    Object reference not set to an instance of an object.

    Καλησπέρα παιδιά.

    Έχω το εξής πρόβλημα. Έχω φτιάξει μια εφαρμογή που κοιτάει μια βάση δεδομένων SQL και καλώ κάποιες store procedures.
    Το πρόβλημα είναι ότι όταν καλέσω μια οποιαδήποτε store procedure για πρώτη φορά πέρνω το παραπάνω error message. Όταν ξανακαλέσω μια store procedure αργότερα δεν έχω κάποιο error.
    Ο κώδικος που έχω είναι ο παρακάτω.

            cmd = New SqlClient.SqlCommand
            cmd.CommandText = "SP_Categories"
            cmd.CommandType = CommandType.StoredProcedure
            cmd.Connection = Con

            Try

               
    If myReader.IsClosed = False Then
                    myReader.Close()
                End If
            Catch ex As Exception
                MsgBox(ex.Message, MsgBoxStyle.Critical)
            End Try



            If Con.State = ConnectionState.Closed Then
                Con.Open()
            End If
          
            Try
                myReader = cmd.ExecuteReader(CommandBehavior.CloseConnection)
            Catch ex As Exception
                MsgBox(ex.Message, MsgBoxStyle.Critical)
            End Try

    Το myreader είναι δηλωμένο ως εξής
    Public myReader As SqlDataReader


    Μπορείτε να μου πείτε τι πρέπει να κάνω για να μην έχω το error?

    Ευχαριστώ
  •  08-01-2008, 19:16 38961 σε απάντηση της 38960

    Απ: Object reference not set to an instance of an object.

    Δηλώνεις τον myReader, χωρίς να του δώσεις reference κάπου, και μετά καλείς το property IsClosed του. Αυτό λογικά θα σου φέρει null reference, καθώς το myReader δεν "δείχνει" κάπου. Δοκίμασε να τον κλείσεις αφού καλέσεις την ExecuteReader.
    Dimitris-Ilias Gkanatsios
    Developer Evangelist, Microsoft Hellas

    My Blog
    StudentGuru
    Twitter
    Facebook
  •  08-01-2008, 19:59 38962 σε απάντηση της 38961

    Απ: Object reference not set to an instance of an object.

    Το κλείνω αφού καλέσω την ExecuteReader.
    Απλά δεν ξέρω αν πρέπει να δηλώσω, και τι, κάτι στην εκκίνηση της εφαρμογής π.χ. ώστε να μην μου πετάει το error την πρώτη φορά.
  •  08-01-2008, 21:11 38963 σε απάντηση της 38961

    Απ: Object reference not set to an instance of an object.

    dt008:
    Δοκίμασε να τον κλείσεις αφού καλέσεις την ExecuteReader.

    Δεν το έγραψα τελείως καλά εδώ, εννοούσα βγάλε τον έλεγχο από κει που τον έχεις (αυτά που έχεις μαρκάρει με κόκκινο) και βάλτα μετά την ExecuteReader.


    Dimitris-Ilias Gkanatsios
    Developer Evangelist, Microsoft Hellas

    My Blog
    StudentGuru
    Twitter
    Facebook
  •  08-01-2008, 23:16 38964 σε απάντηση της 38960

    Απ: Object reference not set to an instance of an object.

    Εφόσον δεν χρησιμοποιείς το DataReader για κάτι άλλο, μπορείς να μεταφέρεις τη δήλωση του ακριβώς στο σημείο που τον χρησιμοποιείς. Μπορείς επιπλέον να χρησιμοποιήσεις το Using statement για να εξασφαλίσεις ότι ο DataReader θα κλείνει πάντα, ακόμα και αν υπάρχει exception. Το ίδιο μπορείς να κάνεις και για το connection:

    cmd = New SqlClient.SqlCommand
    cmd.CommandText = "SP_Categories"
    cmd.CommandType = CommandType.StoredProcedure

    Try
        Using Con As SqlConnection = New SqlConnection(connectionString)
            cmd.Connection = Con
            Using myReader As SqlDataReader=cmd.ExecuteReader()
            ....
            End Using
        End Using
    Catch ex As Exception
        MsgBox(ex.Message, MsgBoxStyle.Critical)
    End Try

    Γενικά, είναι πολύ καλή πρακτική να δηλώνεις μία μεταβλητή όσο πιο κοντά γίνεται στο σημείο όπου θα χρησιμοποιηθεί, ακριβώς για να αποφύγεις προβλήματα σαν αυτό που αντιμετώπισες. Άλλη καλή τακτική είναι να θέτεις τιμή στην μεταβλητή στην ίδια γραμμή όπου κάνεις τον ορισμό. Έτσι εξασφαλίζεις ότι η μεταβλητή σου θα φαίνεται μόνο μέσα στο block που χρησιμοποιείται.


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  09-01-2008, 08:49 38969 σε απάντηση της 38964

    Απ: Object reference not set to an instance of an object.

    Ευχαριστώ. Επιτέλους δεν έχω το ενοχλητικό μήνυμα Stick out tongue
  •  09-01-2008, 10:41 38974 σε απάντηση της 38964

    Απ: Object reference not set to an instance of an object.

    Παναγιώτης Καναβός:

    Εφόσον δεν χρησιμοποιείς το DataReader για κάτι άλλο, μπορείς να μεταφέρεις τη δήλωση του ακριβώς στο σημείο που τον χρησιμοποιείς. Μπορείς επιπλέον να χρησιμοποιήσεις το Using statement για να εξασφαλίσεις ότι ο DataReader θα κλείνει πάντα, ακόμα και αν υπάρχει exception. Το ίδιο μπορείς να κάνεις και για το connection:

    cmd = New SqlClient.SqlCommand
    cmd.CommandText = "SP_Categories"
    cmd.CommandType = CommandType.StoredProcedure

    Try
        Using Con As  = New SqlConnection(connectionString)
            cmd.Connection = Con
            Using myReader As SqlDataReader=cmd.ExecuteReader()
            ....
            End Using
        End Using
    Catch ex As Exception
        MsgBox(ex.Message, MsgBoxStyle.Critical)
    End Try

    Γενικά, είναι πολύ καλή πρακτική να δηλώνεις μία μεταβλητή όσο πιο κοντά γίνεται στο σημείο όπου θα χρησιμοποιηθεί, ακριβώς για να αποφύγεις προβλήματα σαν αυτό που αντιμετώπισες. Άλλη καλή τακτική είναι να θέτεις τιμή στην μεταβλητή στην ίδια γραμμή όπου κάνεις τον ορισμό. Έτσι εξασφαλίζεις ότι η μεταβλητή σου θα φαίνεται μόνο μέσα στο block που χρησιμοποιείται.



    Αν ο κώδικας χτυπήσει στο SqlDataReader=cmd.ExecuteReader() τότε θα πάει και θα εκτελεστεί το catch. Θα έχει κλείσει όμως το Connection? Εγώ συνήθως το γράφω ως εξής:

    Dim MyConnection As System.Data.SqlClient.SqlConnection = Nothing
    Dim MyTransaction As System.Data.SqlClient.SqlTransaction = Nothing
    dim i as integer

    Try
        MyConnection = New System.Data.SqlClient.SqlConnection(Declarations.strConn)
        MyConnection.Open()
        MyTransaction = MyConnection.BeginTransaction(System.Data.IsolationLevel.Serializable)
        Dim strSQL as string = "μπλα μπλα"

        Using MyCommand As New System.Data.SqlClient.SqlCommand(strSQL, MyConnection, MyTransaction)
            MyCommand.CommandType = Data.CommandType.Text
            MyCommand.Parameters.AddWithValue("@μπλαμπλα", value)
            i = MyCommand.ExecuteNonQuery
        End Using

        If i = <value> Then
            <do something>
        End if

    Catch ex As Exception
        <Μπλα μπλα>

    Finally
        If <κάποια συνθήκη> Then
            MyTransaction.Rollback()
        Else
            MyTransaction.Commit()
        End If

        If MyConnection IsNot Nothing Then
            MyConnection.Close()
        End If
    End Try


    Έτσι βάζοντας το
    If MyConnection IsNot Nothing Then
        MyConnection.Close()
    End If


    στο finally εξασφαλίζω ότι θα κλείσει το connection. Είναι πλεονασμός αυτός;

    Διαμάντης


    A wise man does not urinate against the wind Smile
  •  09-01-2008, 14:29 38989 σε απάντηση της 38974

    Απ: Object reference not set to an instance of an object.

    Αυτά που γράφεις αναλαμβάνει να τα κάνει το Using statement. Στο End Using καλεί αυτόματα την Dispose μέθοδο της μεταβλητής που ορίστηκε με Using, ακόμα και αν υπάρχει Exception. Η Dispose του SqlDataReader και του SqlConnection καλεί την Close.

    Ρίξε μία ματιά στο documentation της Using, γιατί φτιάχτηκε ακριβώς για τέτοιες περιπτώσεις.


    Παναγιώτης Καναβός, Freelancer
    Twitter: http://www.twitter.com/pkanavos
  •  09-01-2008, 15:21 38998 σε απάντηση της 38989

    Απ: Object reference not set to an instance of an object.

    Παναγιώτης Καναβός:

    Ρίξε μία ματιά στο documentation της Using, γιατί φτιάχτηκε ακριβώς για τέτοιες περιπτώσεις.


    Ναι, το έκανα και έχεις δίκιο:


    A Using block behaves like a Try...Finally construction in which the Try block uses the resources and the Finally block disposes of them. Because of this, the Using block guarantees disposal of the resources, no matter how you exit the block. This is true even in the case of an unhandled exception, except for a StackOverflowException.


    A wise man does not urinate against the wind Smile
Προβολή Τροφοδοσίας RSS με μορφή XML
Με χρήση του Community Server (Commercial Edition), από την Telligent Systems