2010-12-02 3 views
0

J'ai une fonction comme celui-ciréférence d'objet non définie à une instance d'objet

public void GetTablesWithUpperCaseName() 
{ 
    SqlConnectionStringBuilder objConnectionString = new SqlConnectionStringBuilder(); 
    objConnectionString.DataSource = txtHost.Text; 
    objConnectionString.UserID = txtUsername.Text; 
    objConnectionString.Password = txtPassword.Text; 
    objConnectionString.InitialCatalog = Convert.ToString(cmbDatabases.SelectedValue); 

    SqlConnection sConnection = new SqlConnection(objConnectionString.ConnectionString); 

    //To Open the connection. 
    sConnection.Open(); 

    //Query to select table_names that have their names in uppercase letters. 
    string selectTablesWithUppercaseName = @"SELECT 
               NAME 
              FROM 
               sysobjects 
              WHERE 
               UPPER(name) COLLATE Latin1_General_BIN = name COLLATE Latin1_General_BIN 
               AND 
               OBJECTPROPERTY(ID,N'IsTable')=1 
               AND 
               OBJECTPROPERTY(ID,N'IsMSShipped')=0 "; 
    //Create the command object 
    SqlCommand sCommand = new SqlCommand(selectTablesWithUppercaseName, sConnection); 

    try 
    { 
     //Create the dataset 
     DataSet dsListOfTablesWithUppercaseName = new DataSet("sysobjects"); 

     //Create the dataadapter object 
     SqlDataAdapter sDataAdapter = new SqlDataAdapter(selectTablesWithUppercaseName, sConnection); 

     //Provides the master mapping between the sourcr table and system.data.datatable 
     sDataAdapter.TableMappings.Add("Table", "sysobjects"); 

     //Fill the dataset 
     sDataAdapter.Fill(dsListOfTablesWithUppercaseName); 

     //Bind the result combobox with foreign key table names 
     DataViewManager dvmListOfForeignKeys = dsListOfTablesWithUppercaseName.DefaultViewManager; 
     dgResultView.DataSource = dsListOfTablesWithUppercaseName.Tables["sysobjects"]; 
    } 
    catch(Exception ex) 
    { 
     //All the exceptions are handled and written in the EventLog. 
     EventLog log = new EventLog("Application"); 
     log.Source = "MFDBAnalyser"; 
     log.WriteEntry(ex.Message); 
    } 
    finally 
    { 
     //If connection is not closed then close the connection 
     if(sConnection.State != ConnectionState.Closed) 
     { 
      sConnection.Close(); 
     } 
    } 
} 

Et une autre fonction pour compter les lignes générées à partir des fonctions précédentes. Mais cette fonction

Null Exception de référence ou d'un objet référence non définie à une instance de objet ..

Quelqu'un peut-il me aider dans ce ... pourquoi il rattrape l'erreur que pour les fonctions ci-dessus et fonctionne bien pour toutes les autres fonctions similaires.

private void UpdateLabelText() 
{ 
    SqlConnectionStringBuilder objConnectionString = new SqlConnectionStringBuilder(); 
    objConnectionString.DataSource = txtHost.Text; 
    objConnectionString.UserID = txtUsername.Text; 
    objConnectionString.Password = txtPassword.Text; 
    objConnectionString.InitialCatalog = Convert.ToString(cmbDatabases.SelectedValue); 

    SqlConnection sConnection = new SqlConnection(objConnectionString.ConnectionString); 

    //To Open the connection. 
    sConnection.Open(); 

    try 
    { 
     int SelectedCellTotal = 0; 
     int counter; 

     // Iterate through the SelectedCells collection and sum up the values. 
     for(counter = 0;counter < (dgResultView.SelectedCells.Count);counter++) 
     { 
      if(dgResultView.SelectedCells[counter].FormattedValueType == Type.GetType("System.String")) 
      { 
       string value = null; 

       // If the cell contains a value that has not been commited, 
       if(dgResultView.IsCurrentCellDirty == true) 
       { 
        value = dgResultView.SelectedCells[counter].EditedFormattedValue.ToString(); 
       } 
       else 
       { 
        value = dgResultView.SelectedCells[counter].FormattedValue.ToString(); 
       } 
       if(value != null) 
       { 
        // Ignore cells in the Description column. 
        if(dgResultView.SelectedCells[counter].ColumnIndex != dgResultView.Columns["TABLE_NAME"].Index) 
        { 
         if(value.Length != 0) 
         { 
          SelectedCellTotal += int.Parse(value); 
         } 
        } 
       } 
       } 
      } 

      // Set the labels to reflect the current state of the DataGridView. 
      lblDisplay.Text = "There are Total " + dgResultView.RowCount + cmbOperations.SelectedItem.ToString(); 
     } 
     catch(Exception ex) 
     { 
      //All the exceptions are handled and written in the EventLog. 
      EventLog log = new EventLog("Application"); 
      log.Source = "MFDBAnalyser"; 
      log.WriteEntry(ex.Message); 
     } 
     finally 
     { 
      //If connection is not closed then close the connection 
      if(sConnection.State != ConnectionState.Closed) 
      { 
       sConnection.Close(); 
      } 
     } 
    } 

De même, lblDisplay.Text ne prend pas les espaces appropriés.

En attente de réponse

+6

Vous avez fourni beaucoup de code ... quelle ligne lève l'exception? –

+3

Ce (mur de) code commence à sembler familier. –

+0

Et pourquoi créez-vous et ouvrez-vous un 'SqlConnection' dans votre deuxième méthode ?? Vous ne l'utilisez nulle part ... –

Répondre

4

OK, je n'ai pas vraiment une réponse pourquoi vous obtenez une « exception de référence null » - mais quelques points à jeter, néanmoins:

  • J'utiliser sys.tables au lieu de sysobjects et d'avoir à préciser quel type d'objet à la requête pour

  • TOUJOURS mettre votre usage unique SqlConnection et SqlCommand en using(.....) { ...... } blocs. De cette façon, vous aurez pas besoin des blocs finally {..} et .NET prendra soin de disposer correctement de ces objets quand ils ne sont plus nécessaires

  • pourquoi utilisez-vous un DataSet quand vous avez seulement une seule table à l'intérieur ?? C'est juste inutile overhead - utilisez un DataTable à la place!

  • ne pas ouvrir le SqlConnection que tôt - attendre jusqu'à la dernière minute, ouvrez-le, d'exécuter la requête, fermez-le à nouveau tout de suite

  • En fait, lorsque vous utilisez le SqlDataAdapter, vous n'avez pas besoin pour ouvrir la SqlConnection vous du tout - le SqlDataAdapter va le faire pour vous (et fermez-le à nouveau après l'avoir fait la lecture des données)

  • do pas mélanger la récupération des données de la base de données avec la liaison à l'élément de l'interface utilisateur - c'est une très mauvaise pratique.De la méthode GetTablesWithUpperCaseName, vous devez retourner quelque chose (comme un DataTable) à l'appelant (l'interface utilisateur) et laisser l'interface utilisateur gère le processus de liaison

  • dans le même sens: cette méthode ne doit pas être saisir des choses de l'interface utilisateur éléments (comme les zones de texte) lui-même - passer dans ces valeurs en tant que paramètres de méthode pour obtenir un code plus propre - celui que vous pourrait effectivement être en mesure de réutiliser dans un autre projet un jour

Voilà comment je pense votre première méthode devrait ressembler à

public DataTable GetTablesWithUpperCaseName(string server, string database, 
               string username, string password) 
    { 
     // Create the datatable 
     DataTable dtListOfTablesWithUppercaseName = new DataTable("tableNames"); 

     SqlConnectionStringBuilder objConnectionString = new SqlConnectionStringBuilder(); 
     objConnectionString.DataSource = server;; 
     objConnectionString.UserID = username; 
     objConnectionString.Password = password; 
     objConnectionString.InitialCatalog = database; 

     // Define the Query against sys.tables - much easier and cleaner! 
     string selectTablesWithUppercaseName = 
      "SELECT NAME FROM sys.tables WHERE UPPER(name) COLLATE Latin1_General_BIN = name COLLATE Latin1_General_BIN AND is_msshipped = 0"; 

     // put your SqlConnection and SqlCommand into using blocks! 
     using (SqlConnection sConnection = new SqlConnection(objConnectionString.ConnectionString)) 
     using (SqlCommand sCommand = new SqlCommand(selectTablesWithUppercaseName, sConnection)) 
     { 
      try 
      { 
       // Create the dataadapter object 
       SqlDataAdapter sDataAdapter = new SqlDataAdapter(selectTablesWithUppercaseName, sConnection); 

       // Fill the datatable - no need to open the connection, the SqlDataAdapter will do that all by itself 
       // (and also close it again after it is done) 
       sDataAdapter.Fill(dtListOfTablesWithUppercaseName); 
      } 
      catch (Exception ex) 
      { 
       //All the exceptions are handled and written in the EventLog. 
       EventLog log = new EventLog("Application"); 
       log.Source = "MFDBAnalyser"; 
       log.WriteEntry(ex.Message); 
      } 
     } 

     // return the data table to the caller 
     return dtListOfTablesWithUppercaseName; 
    } 
Questions connexes