从方法返回datareader

and*_*ter 7 c# asp.net

我有以下方法

    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;
    }
Run Code Online (Sandbox Code Playgroud)

我这样称呼

        SqlDataReader reader = MenuDataReader(url);
        if (reader.HasRows)
        {
            while (reader.Read())
            { }}
Run Code Online (Sandbox Code Playgroud)

但我收到错误信息

读取器关闭时无效尝试调用HasRows.

谁能帮我吗

谢谢

小智 17

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;
     }
  }
Run Code Online (Sandbox Code Playgroud)

  • 连接是否保持打开状态? (2认同)

Joe*_*orn 12

你真的需要读者吗,或者你只是需要一些方法来迭代它里面的行?我建议使用迭代器块.您可以在源方法内迭代您的行,然后yield依次遍历调用者.

这种技术有一个转折点:因为你在每次迭代时都会产生相同的对象,所以有些情况会导致问题,所以你最好还要求代理人在某处复制行的内容.我还想将它抽象为可用于任何查询的泛型方法,并使用相同的委托技术来处理参数数据,如下所示:

private IEnumerable<T> GetRows<T>(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<MenuItem>("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( ... );
     }
 }
Run Code Online (Sandbox Code Playgroud)