当我调试我的应用程序时,它会给出一个错误,即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();
}
答案 0 :(得分:4)
那是因为您的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 Reference on SqlDataAdapter.Fill()
根据上述参考文献,引用:
与SELECT语句关联的连接对象必须有效,但不需要打开它。如果在调用Fill之前关闭连接,则会打开它以检索数据,然后关闭。如果在调用Fill之前连接已打开,则它将保持打开状态。
答案 1 :(得分:3)
打开连接并尽快关闭。
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;
}
答案 2 :(得分:2)
不应该是
if (cn == null)
{
cn = new SqlConnection(myConnection);
cn.Open();
}
答案 3 :(得分:1)
虽然塞巴斯蒂安的回答涵盖了错误的很大一部分。这是一个更完整的清单。
您有SQL注入问题。所有查询都应该参数化,否则你会遇到麻烦。特别是当您直接附加用户输入的文本时。
您正在泄漏资源:SqlConnection
和SqlCommand
。这些需要尽可能接近实际利用连接和命令的代码。相信我,Windows能够通过内置连接池处理所有连接的打开/关闭。您无需自己维护。
由于在显示层中使用嵌入式SQL,代码本身很脆弱。举例来说,假设CourseCode
已重命名为CourseId
。您将不得不搜索并修改很多代码文件,以便进行更改。有多种方法可以限制对此问题的曝光;我会留给你研究。
如果我在野外遇到这个代码,我会完全删除ConnectionClass
。没有什么可以为你做的,不应该以更强大的方式在其他地方完成。
接下来,我将删除GetData()
方法。那只是糟糕的代码。你永远不应该接受一个完整的sql字符串并盲目地执行它。在这一段代码中存在许多安全问题。
然后我会重写ClassDataManagement,这样我的SQL(如果我真的希望它保持嵌入式,我不会因为我不按这种方式滚动)是我所有查询的容器。我会有像GetCourseByCourseCode(String courseCode)
这样的好方法来验证courseCode是否为预期格式,然后将其作为查询的参数传递给我的sqlcommand对象。
对于奖励积分,我会通过查看缓存数据可以更好地提供哪些呼叫来扩展上述内容。通过将它们放入已识别的方法中,可以更容易地选择可以来自缓存的内容与我真正需要通过网络运行查询的内容。
接下来,我会确保无论在哪里进行SQL调用,我都会使用子句将SqlConnection,SqlCommand和读者包装起来。这是确保在离开方法之前一切都已正确关闭和处理的最佳方法。什么都没有,你正在招来麻烦。
最后,我会高度考虑使用Enterprise Library进行数据访问。它好多了。
答案 4 :(得分:0)
得到所有建议,解决您当前的问题,您也可以尝试这种方式:
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;
}
}
......
答案 5 :(得分:0)
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;
}
}
}
}