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

时间:2010-12-02 13:07:12

标签: c# .net visual-studio winforms

我有这样的功能

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也没有占用适当的空格。

等待回复

1 个答案:

答案 0 :(得分:4)

好的,我真的没有答案为什么你会得到一个“空引用异常” - 但是还有几点可以投入,但是:

  • 我会使用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;
    }