简体   繁体   English

对象引用未设置为对象的实例

[英]Object reference not set to an instance of object

I have a function like this 我有这样的功能

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();
       }
    }
 }

And another function for counting the rows generated from the previous functions. 另一个功能是对从先前功能生成的行进行计数。 But this function 但是这个功能

Null Reference Exception or Object reference not set to an instance of object.. 空引用异常或对象引用未设置为对象的实例。

Can anyone help me in this... why it is catching error only for the functions above and working fine for all other similar functions. 谁能在这方面帮助我...为什么它仅在上述功能中捕获错误,而在所有其他类似功能中工作正常。

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();
            }
        }
    }

Also the lblDisplay.Text is not taking proper spaces. 另外,lblDisplay.Text没有使用适当的空格。

Waiting for reply 等待回复

OK, I don't really have an answer why you're getting a "null reference exception" - but a few points to throw in, nonetheless: 好的,我真的没有答案,为什么您会收到“空引用异常”-尽管如此,还有一些要点:

  • I would use sys.tables instead of sysobjects and having to specify what type of object to query for 我将使用sys.tables而不是sysobjects ,并且必须指定要查询的对象类型

  • ALWAYS put your disposable SqlConnection and SqlCommand into using(.....) { ...... } blocks. 始终将您的一次性SqlConnectionSqlCommand放入using(.....) { ...... }块中。 That way, you won't need any finally {..} blocks, and .NET will take care of properly disposing of those objects when they're no longer needed 这样,您将不需要任何finally {..}块,并且.NET将在不再需要这些对象时妥善处理这些对象。

  • why do you use a DataSet when you only have a single table inside?? 当内部只有一个表时,为什么要使用DataSet That's just unnecessary overhead - use a DataTable instead! 那只是不必要的开销-改用DataTable

  • don't open the SqlConnection that early - wait 'til the very last moment, open it, execute query, close it again right away 不要提早打开SqlConnection等到最后一刻,将其打开,执行查询,然后再次将其关闭

  • actually, when using the SqlDataAdapter , you don't need to open the SqlConnection yourself at all - the SqlDataAdapter will do that for you (and close it again after it is done reading the data) 实际上,当使用SqlDataAdapter ,您根本不需要自己打开SqlConnection - SqlDataAdapter会为您执行此操作(在完成读取数据后再次关闭它)

  • do not mix the retrieval of the data from the database with the binding to the UI element - this is a very bad practice. 从与绑定到UI元素的数据库混合数据的检索-这是一个非常不好的做法。 From the GetTablesWithUpperCaseName method, you should return something (like a DataTable ) to the caller (the UI) and let the UI handle the binding process GetTablesWithUpperCaseName方法中,您应该向调用方(UI)返回一些内容(如DataTable ),并让UI处理绑定过程

  • along the same lines: that method should not be grabbing stuff from UI elements (like text boxes) itself - pass in those values as method parameters, to get a cleaner code - one that you might actually be able to reuse in another project some day 沿着相同的路线:该方法应该被抓住的UI元素(如文本框)的东西本身-通过在这些值作为方法的参数,以获得更干净的代码-一个你可能实际上是能够在另一个项目中的某一天重用

This is how I think your first method ought to look like 这就是我认为您的第一种方法应该看起来像的样子

    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;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM