繁体   English   中英

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

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

我有这样的功能

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

另一个功能是对从先前功能生成的行进行计数。 但是这个功能

空引用异常或对象引用未设置为对象的实例。

谁能在这方面帮助我...为什么它仅在上述功能中捕获错误,而在所有其他类似功能中工作正常。

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

另外,lblDisplay.Text没有使用适当的空格。

等待回复

好的,我真的没有答案,为什么您会收到“空引用异常”-尽管如此,还有一些要点:

  • 我将使用sys.tables而不是sysobjects ,并且必须指定要查询的对象类型

  • 始终将您的一次性SqlConnectionSqlCommand放入using(.....) { ...... }块中。 这样,您将不需要任何finally {..}块,并且.NET将在不再需要这些对象时妥善处理这些对象。

  • 当内部只有一个表时,为什么要使用DataSet 那只是不必要的开销-改用DataTable

  • 不要提早打开SqlConnection等到最后一刻,将其打开,执行查询,然后再次将其关闭

  • 实际上,当使用SqlDataAdapter ,您根本不需要自己打开SqlConnection - SqlDataAdapter会为您执行此操作(在完成读取数据后再次关闭它)

  • 从与绑定到UI元素的数据库混合数据的检索-这是一个非常不好的做法。 GetTablesWithUpperCaseName方法中,您应该向调用方(UI)返回一些内容(如DataTable ),并让UI处理绑定过程

  • 沿着相同的路线:该方法应该被抓住的UI元素(如文本框)的东西本身-通过在这些值作为方法的参数,以获得更干净的代码-一个你可能实际上是能够在另一个项目中的某一天重用

这就是我认为您的第一种方法应该看起来像的样子

    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