【问题标题】:Invalid attempt to call MetaData when reader is closed?阅读器关闭时调用元数据的尝试无效?
【发布时间】:2011-05-30 17:26:58
【问题描述】:

我正在从数据读取器运行 if else 语句来查询表数据并激活/取消激活页面上的某些控件。我实现了一个 using 语句来在我关闭块时自动关闭连接和阅读器,但我仍然在我的每个 if else 语句中收到阅读器关闭错误。少了什么东西?代码如下:

string comnt = "SELECT StatusId FROM Submission WHERE SubmissionId =" + x;


    using (SqlConnection editConn = new SqlConnection(connectionString))
    {
        editConn.Open();

        using (SqlCommand statCmd = new SqlCommand(comnt, editConn))
        {
            SqlDataReader dr = statCmd.ExecuteReader();
            dr.Read();
            if (dr.GetInt32(0) > 0)
            {
                PanelComment.Visible = true;
                PanelQuote.Visible = false;
                LnbFid.Visible = false;
                LnbCrim.Visible = false;
                LnbEo.Visible = false;
                LnbEpl.Visible = false;
                LnbNot.Visible = false;
                LnbPriv.Visible = false;
                LnbPub.Visible = false;

            }
            else
            {
                PanelComment.Visible = false;
            }

        } 

【问题讨论】:

  • 您确定 reader 返回行吗?它有“HasRows”属性在阅读之前检查
  • “x”代表什么?它是代表字符串的字符串吗?一个号码?你应该习惯使用参数,连接字符串来构建 SQL 查询是危险的,特别是如果 'x' 是用户依赖的。
  • 被查询的字段不会接受空值,所以肯定是返回行@vityanya,而@InBetween,'x'是一个字符串,用来存储页面上jquery的提交id。

标签: c# asp.net sql-server visual-studio datareader


【解决方案1】:

试试这个方法:

if (dr.HasRows)
{
     while (dr.Read())
     {
         if (dr.GetInt32(0) > 0)
         {
             ...
         }
     }
}

欲了解更多信息,请查看此页面:

Retrieving Data Using a DataReader

【讨论】:

  • HasRows 足以清除我的错误 - 不需要第二个 if。对我来说,即使我期待 GUID,但当我执行 dr.GetGuid(0) > 0 时,它会引发错误,因为它作为 char(35) 列而不是 uniqueidentifier 列保存在数据库中——永远不会通过 @ 987654326@ 在这种情况下进行测试。所以让买家小心那个,虽然我承认我有一个特殊情况......
【解决方案2】:

您的查询没有返回任何结果。如果您不确定查询是否会返回任何数据,请习惯以下构造:

while (dr.Read()) //will return true while there is data to be read.
{
    ...
}

【讨论】:

  • 谢谢@InBetween。我不确定为什么查询不会返回结果,因为该字段是非空的,并且对 db 表的检查显示数据在那里。
  • @brazos:如果提交 ID 不是数字,您的查询字符串中可能会缺少 ''。如果是数字检查任何本地化问题。
  • 是否为空,此构造不会阻止错误。即使我只是在调试模式下进行SELECT * FROM Authors 类型的查询,我也遇到过。
【解决方案3】:

由于阅读器名称不匹配,我遇到了这个问题。即

SqlCommand sqlmd = new SqlCommand();
SqlDataReader sqldr = sqlmd.ExecuteReader();
while (sqldr.Read())
{

    idd = (int)rdr["Id"];
}

后来我换了代码

 idd = (int)sqldr["Id"];

错误已解决。

【讨论】:

    【解决方案4】:

    似乎 select 语句没有返回任何行 当你第一次调用 dr.Read() datareader 将立即关闭 对于使用数据阅读器,我们总是显示使用 if 或 while 就像莱尼尔所说的那样

       using (SqlCommand statCmd = new SqlCommand(comnt, editConn))
        {
            SqlDataReader dr = statCmd.ExecuteReader();
           if( dr.Read())
            if (dr.GetInt32(0) > 0)
            {
                PanelComment.Visible = true;
                PanelQuote.Visible = false;
                LnbFid.Visible = false;
                LnbCrim.Visible = false;
                LnbEo.Visible = false;
                LnbEpl.Visible = false;
                LnbNot.Visible = false;
                LnbPriv.Visible = false;
                LnbPub.Visible = false;
    
            }
            else
            {
                PanelComment.Visible = false;
            }
    
        }
    

    【讨论】:

      【解决方案5】:
      if (conn.State == ConnectionState.Closed)
          conn.Open();
      
          SqlCommand qr1 = new SqlCommand("select TransID, FType, FldName, LTrans, 
              OnCCBeforeLoad, LTop, LLeft, LWidth, LHeight, LFColor 
              from jwOndropExecButtonS where active = 'T' and MyType = ''  
              and LTrans = '" + TmpRajTransID + "' order by dbo.val(TransID) ", conn);
          SqlDataReader d1 = qr1.ExecuteReader();
          while (d1.Read())
          {
              if (d1.HasRows)
              {
                  string MrFldName = d1["FldName"].ToString().Trim();
      
                  if (d1["OnCCBeforeLoad"].ToString().Trim() == "Clr")
                      ClearValueandToolTipforFieldName(MrFldName);
                  if (d1["LTop"].ToString().Trim() != "")
                      DisplaySetTopValue(MrFldName, d1["LTop"].ToString().Trim());
                  if (d1["LLeft"].ToString().Trim() != "")
                      DisplaySetLeftValue(MrFldName, d1["LLeft"].ToString().Trim());
                  if (d1["LWidth"].ToString().Trim() != "")
                      DisplaySetWidthValue(MrFldName, d1["LWidth"].ToString().Trim());
                  if (d1["LHeight"].ToString().Trim() != "")
                      DisplaySetHeightValue(MrFldName, d1["LHeight"].ToString().Trim());
                  if (d1["FType"].ToString().Trim() == "Visible")
                      ShowTextBoxWithFldName(MrFldName);
                  if (d1["FType"].ToString().Trim() == "InVisible")
                      HideandClearTextBoxWithFldName(MrFldName);
                  if (d1["FType"].ToString().Trim() == "InNVisible")
                      HideOnlyTextBoxWithFldName(MrFldName);
                  if (d1["FType"].ToString().Trim() == "Enable")
                      SetEnableforFieldName(MrFldName);
                  if (d1["FType"].ToString().Trim() == "Disable")
                      SetDisableforFieldName(MrFldName);
              }
          }
          d1.Close();
          if (conn.State == ConnectionState.Open)
              conn.Close();
      

      我偶尔会遇到同样的错误

      if (d1["FType"].ToString().Trim() == "Visible") 
      

      metadata not found。后来发现没有关闭阅读器,是ASP.NET程序占用内存过多自动关闭了阅读器。主要取决于SQL server阶段。如果是常规错误,请检查您的连接。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-08-26
        • 2012-09-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多