从方法返回datareader
我有以下方法
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; }
我这样称呼
SqlDataReader reader = MenuDataReader(url); if (reader.HasRows) { while (reader.Read()) { }}
但我收到错误信息
读取器关闭时无效尝试调用HasRows。
谁能帮我吗
谢谢
你真的需要读者,还是只需要某种方法来迭代它里面的行? 我建议使用迭代器块 。 您可以在源方法内迭代您的行,并依次将每一行yield
给调用者。
这种技术有一个转折点:因为你在每次迭代时都会产生相同的对象,所以有些情况会导致问题,所以你最好也要求代理人在某处复制行的内容。 我还想将它抽象为可用于任何查询的generics方法,并使用相同的委托技术来处理参数数据,如下所示:
private IEnumerable GetRows (string sql, Action addParameters, Func 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
如https://msdn.microsoft.com/en-us/library/system.data.sqlclient.sqlcommand(v=vs.110).aspx中所示 :
public static SqlDataReader ExecuteReader(String connectionString, String commandText, CommandType commandType, params SqlParameter[] parameters) { SqlConnection conn = new SqlConnection(connectionString); using (SqlCommand cmd = new SqlCommand(commandText, conn)) { cmd.CommandType = commandType; cmd.Parameters.AddRange(parameters); conn.Open(); // When using CommandBehavior.CloseConnection, the connection will be closed when the // IDataReader is closed. SqlDataReader reader = cmd.ExecuteReader(CommandBehavior.CloseConnection); return reader; } }
我不会返回读者 – 您的连接和命令的处理正在关闭连接。 我会返回一个代表性的数据模型。
当您在using
语句中返回时,代码会在SqlConnection
上调用Dispose
。 这会关闭DataReader
,从而导致错误。