[英]How can I “detach” a SqlDataReader from its SqlConnection object?
[英]Where to close SqlDataReader object and SqlConnection object?
我调用一个函数,该函数将SqlDataReader
对象返回到调用语句。 我很困惑应该在哪里关闭SqlDataReader
对象和SqlConnection
对象? 在函数中还是在调用之后?
这是函数调用:
SqlDataReader dr2= RetrieveSearcher();
pid = dr2[0].ToString();
这是功能:
protected SqlDataReader RetrieveSearcher()
{
String Q = "select price from tb3 where pid='12';
cn = new SqlConnection("data source=.\\sqlexpress; integrated security=true; initial catalog=singh");
cn.Open();
cmd = new SqlCommand(Q,cn);
dr1 = cmd.ExecuteReader();
dr1.Read();
return dr1;
}
using
块中,例如Connections,Commands,DataReaders等。这可确保即使发生异常也不会保持打开资源的状态。 price
示例似乎确实应该是十进制或数字值,而不是字符串,因此请勿将其存储为字符串,也不要将其读回为字符串。 更改您的方法以返回自定义类型,例如一条数据。 这样可以确保适当的SoS(关注点分离)。 不要返回DataReader! 这将从调用者那里提取整个数据库调用,这是您应该努力的目标。
protected SomeType RetrieveSearcherData(string pid)
{
const string Q = "SELECT price FROM tb3 WHERE pid = @pid";
using(var cn=new SqlConnection())
using(var cmd=new SqlCommand(Q,cn))
{
// I do not know what pid is but use tho correct type here as well and specify that type using SqlDbType
cmd.Parameters.Add(new SqlParameter("@pid", SqlDbType.VarChar, 100) { Value = pid});
cn.Open();
using(var dr1= cmd.ExecuteReader())
{
if(dr1.Read())
{
var result = dr1.GetDecimal(0);
// read something and return it either in raw format or in some object (use a custom type)
}
else
return null; // return something else that indicates nothing was found
}
}
}
您是否真的想在每次调用此功能时打开一个连接? 让一个线程处理多个连接是获得死锁的肯定方法。
如果您仍然想做#1,我建议您让RetrieveSearcher
以List<T>
或heck的形式返回所需的DataTable
,只需返回一个DataTable
并进行处理即可。 这样,函数可以关闭其打开的连接。
如果您仍然真的想返回SqlDataReader
则需要确保可以关闭打开的连接。 SqlDataReader
不会直接公开SqlConnection
,因此,在离开RetrieveSearcher
方法后, 无法直接关闭连接。 但是,您可以这样做:
dr1 = cmd.ExecuteReader(CommandBehavior.CloseConnection);
当阅读器关闭时,这将关闭连接。 因此,您可以执行以下操作:
using (SqlDataReader dr2 = RetrieveSearcher()) { pid=dr2[0].ToString(); }
我当然假设您确实需要多个字符串。 :)如果您只需要一个字符串,则只需返回该字符串并调用cmd.ExecuteScalar();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.