SelelectCommad.connection属性未初始化

本文关键字:初始化 属性 connection SelelectCommad | 更新日期: 2023-09-27 18:22:39

调试应用程序时,会出现SelectCommand.Connection属性未初始化的错误。我不知道我在这里做错了什么:s。实际上,我想在搜索文本框的textchanged事件时添加一个过滤器。

public class ConnectionClass
{
    static SqlConnection cn;
    public static SqlConnection Connection()
    {
        string myConnection = ConfigurationManager.ConnectionStrings["_uniManagementConnectionString1"].ConnectionString;
        if (cn != null)
        {
            cn = new SqlConnection(myConnection);
            cn.Open();
        }
        return cn;
    }
}    
public class ClassDataManagement 
{ 
    SqlConnection cn = ConnectionClass.Connection();
    public DataTable GetData(string SQL)
    {
         SqlCommand cmd = new SqlCommand(SQL, cn);
         SqlDataAdapter da = new SqlDataAdapter(cmd);
         DataTable dt = new DataTable();
         da.Fill(dt);
         return dt;
    } 
}
protected void TextBoxFilterText_TextChanged(object sender, EventArgs e)
{
   ClassDataManagement dm = new ClassDataManagement();
   string query = "Select CourseCode from _Courses where coursecode like'%" + TextBoxFilterText.Text.TrimEnd() + "%'";
   dm.GetData(query);
   GridViewCourses.DataBind();
}

SelelectCommad.connection属性未初始化

这是因为cn变量是null,并且没有初始化。还有一个例子,说明在静态方法中初始化和打开数据库连接是个坏主意。

试试这个:

public class ClassDataManagement 
{ 
   public DataTable GetData(string SQL)
    {
          string YourConnectionString = ConfigurationManager.ConnectionStrings["_uniManagementConnectionString1"].ConnectionString;     
          DataTable dt = new DataTable();             
          using (SqlConnection cn = new SqlConnection(YourConnectionString))
          using (SqlCommand cmd = new SqlCommand(SQL, cn))
          using (SqlDataAdapter da = new SqlDataAdapter(cmd))
          {
              da.Fill(dt);
          }
          return dt;
    } 
}

使用SqlDataAdapter类,您不需要显式调用SqlConnection.Open()SqlDataAdapter.Fill()方法处理所有的连接打开(和关闭)。

MSDN关于SqlDataAdapter.Fill() 的参考资料

根据上述参考,引用:

与SELECT语句关联的连接对象必须有效,但不需要打开。如果在调用Fill之前关闭了连接,则会打开该连接以检索数据,然后关闭。如果在调用Fill之前连接处于打开状态,则它将保持打开状态。

打开连接并尽快关闭。

    public DataTable GetData(string commandString)
    {
        var result = new DataTable();
        using (var cn = new SqlConnection(ConfigurationManager.ConnectionStrings["_uniManagementConnectionString1"].ConnectionString))
            using (var cmd = new SqlCommand(commandString, cn))
                using (var da = new SqlDataAdapter(cmd))
                {
                    da.Fill(result);
                }
        return result;
    }

那不应该是吗

if (cn == null)
{
    cn = new SqlConnection(myConnection);
    cn.Open();
}

尽管Sebastian的回答涵盖了大部分错误。这是一个更完整的列表。

  1. 您有SQL注入问题。所有的查询都应该参数化,否则你就麻烦了。尤其是当您直接附加用户输入的文本时。

  2. 您正在泄漏资源:SqlConnectionSqlCommand。这些需要尽可能接近实际使用连接和命令的代码。相信我,Windows完全能够通过内置连接池处理所有打开/关闭连接的操作。你不需要自己维护。

  3. 由于在显示层中使用了嵌入式SQL,代码本身很脆弱。举个例子,假设CourseCode被重命名为CourseId。您可能需要搜索和修改大量代码文件才能进行更改。有多种方法可以限制接触这一问题;我把它留给你研究。

如果我在野外遇到这段代码,我会完整地删除ConnectionClass。没有什么能为你做的,不应该在其他地方以更稳健的方式做。

接下来,我将删除GetData()方法。这只是错误的代码。你永远不应该接受一个完整的sql字符串并盲目地执行它。仅仅在这一块代码中就有很多安全问题。

然后我会重写ClassDataManagement,这样我的SQL(如果我真的想让它保持嵌入式,我不会这样做,因为我不会这样滚动)就是我所有查询的容器。我会有像GetCourseByCourseCode(String courseCode)这样的好方法,它会验证courseCode是否为预期格式,然后将其作为查询的参数传递给我的sqlcommand对象。

对于奖励积分,我将在上面的基础上进行扩展,看看缓存数据可以更好地为哪些调用提供服务。通过将它们放在已识别的方法中,可以更容易地从缓存中选择可以来自的内容,而不是我真正需要通过网络运行查询的内容。

接下来,我将确保无论在哪里进行SQL调用,我的SqlConnection、SqlCommand和读取器都使用子句进行包装。这是在离开该方法之前确保所有东西都正确关闭和处理的最佳方法。如果少了一点,你就会惹麻烦。

最后,我会高度考虑使用企业库进行数据访问。好多了。

在给出了所有建议后,为了解决您当前的问题,您也可以尝试以下方法:

 public class ConnectionClass
 {
 static SqlConnection cn;
   public static SqlConnection Connection()
    {
       string myConnection = ConfigurationManager.ConnectionStrings["_uniManagementConnectionString1"].ConnectionString;
       return new SqlConnection(myConnection);
      }
   }    
public class ClassDataManagement 
{       
 public DataTable GetData(string SQL)
   {
    using (SqlConnection cn = ConnectionClass.Connection())
     {
     //SqlCommand cmd = new SqlCommand(SQL, cn);
     SqlDataAdapter da = new SqlDataAdapter(SQL,cn);
     DataTable dt = new DataTable();
     da.Fill(dt);
     return dt;
     }
   } 
......
public DataTable GetData()
{
    using (System.Data.SqlClient.SqlConnection con = new SqlConnection("YourConnection string"))
    {
        con.Open();
        using (SqlCommand cmd = new SqlCommand())
        {
            string expression = "Parameter value";
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandText = "Your Stored Procedure";
            cmd.Parameters.Add("Your Parameter Name",
                        SqlDbType.VarChar).Value = expression;
            cmd.Connection = con;
            using (SqlDataAdapter da = new SqlDataAdapter(SQL, cn))
            {
                DataTable dt = new DataTable();
                da.Fill(dt);
                return dt;
            }
        }
    }
}