从方法返回的DataReader [英] Return datareader from method
问题描述
我有以下方法
public static SqlDataReader MenuDataReader(string url)
{
using (SqlConnection con = new SqlConnection(connectionString))
{
using (SqlCommand cmd = new SqlCommand("spR_GetChildMenus", con))
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("@PageUrl", url);
cmd.Parameters.AddWithValue("@MenuId", ParameterDirection.Output);
cmd.Parameters.AddWithValue("@ParentId", ParameterDirection.Output);
cmd.Parameters.AddWithValue("@TitleText", ParameterDirection.Output);
cmd.Parameters.AddWithValue("@ExternalUrl", ParameterDirection.Output);
cmd.Parameters.AddWithValue("@FullUrl", ParameterDirection.Output);
cmd.Parameters.AddWithValue("@ChildCount", ParameterDirection.Output);
con.Open();
SqlDataReader reader = cmd.ExecuteReader();
if (reader.HasRows)
{
//return reader;
while (reader.Read())
{
return reader;
}
}
}
}
return null;
}
这IM调用像这样
which im calling like this
SqlDataReader reader = MenuDataReader(url);
if (reader.HasRows)
{
while (reader.Read())
{ }}
然而即时得到错误信息
however im getting the error message
无效试图调用HasRows当读者是封闭的。
Invalid attempt to call HasRows when reader is closed.
谁能帮我出
感谢
推荐答案
你真的需要的读者,还是你只是需要一些方法来遍历里面的行?我建议一个的迭代器块的。您可以将行遍历源法里面,收益
各行依次调用者。
Do you really need the reader, or do you just need some way to iterate over the rows inside it? I suggest an iterator block. You can iterate over your rows inside the source method, and yield
each row in turn to the caller.
有与此技术一拧:因为你的收益的相同的每次迭代,有些情况下这可能会导致一个问题,所以你最好也要求对象委托某处复制行的内容。我也喜欢到可以用于任何的查询,并使用相同的代表技术来处理参数的数据,像这样的抽象给通用方法:
There is a twist with this technique: because you're yielding the same object with each iteration, there are cases where this can cause a problem, and so you're best off also asking for a delegate to copy the contents of the row somewhere. I also like to abstract this to a generic method that can be used for any query, and use the same delegate technique to handle parameter data, like so:
private IEnumerable<T> GetRows(string sql, Action<SqlParameterCollection> addParameters, Func<IDataRecord, T> copyRow)
{
using (var cn = new SqlConnection("Connection string here"))
using (var cmd = new SqlCommand(sql, cn)
{
cmd.CommandType = CommandType.StoredProcedure;
addParameters(cmd.Parameters);
cn.Open();
using (var rdr = cmd.ExecuteReader())
{
while (rdr.Read())
{
yield return copyRow(rdr);
}
rdr.Close();
}
}
}
public IEnumerable<MenuItem> GetChildMenus(string url)
{
return GetRows("spR_GetChildMenus", p =>
{
//these lines are copied from your question, but they're almost certainly wrong
p.AddWithValue("@PageUrl", url);
p.AddWithValue("@MenuId", ParameterDirection.Output);
p.AddWithValue("@ParentId", ParameterDirection.Output);
p.AddWithValue("@TitleText", ParameterDirection.Output);
p.AddWithValue("@ExternalUrl", ParameterDirection.Output);
p.AddWithValue("@FullUrl", ParameterDirection.Output);
p.AddWithValue("@ChildCount", ParameterDirection.Output);
}, r =>
{
return new MenuItem( ... );
}
}
这篇关于从方法返回的DataReader的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!