当读取器关闭时调用FieldCount的尝试无效。

6

当我尝试从数据库中读取数据时,出现了上述错误。我知道里面有两行数据,所以不是因为没有实际数据存在。

这可能是CommandBehavior.CloseConnection引起的问题吗?我被告知在ExecuteReader之后必须立即执行此操作。这正确吗?

        try
        {
            _connection.Open();
            using (_connection)
            {
                SqlCommand command = new SqlCommand("SELECT * FROM Structure", _connection);
                SqlDataReader dataReader = command.ExecuteReader(CommandBehavior.CloseConnection);

                if (dataReader == null) return null;

                var newData = new List<Structure>();
                while (dataReader.Read())
                {
                    var entity = new Structure
                    {
                        Id = (int)dataReader["StructureID"],
                        Path = (string)dataReader["Path"],
                        PathLevel = (string)dataReader["PathLevel"],
                        Description = (string)dataReader["Description"]
                    };

                    newData.Add(entity);
                }
                dataReader.Close();

                return newData;
            }
        }
        catch (SqlException ex)
        {
            AddError(new ErrorModel("An SqlException error has occured whilst trying to return descendants", ErrorHelper.ErrorTypes.Critical, ex));
            return null;
        }
        catch (Exception ex)
        {
            AddError(new ErrorModel("An error has occured whilst trying to return descendants", ErrorHelper.ErrorTypes.Critical, ex));
            return null;
        }
        finally
        {
            _connection.Close();
        }
    }

感谢您提前提供的任何帮助。

克莱尔

5个回答

3

当您在C#中使用Using语句时,在using的最后一个}之后,连接会自动关闭,这就是为什么在尝试读取它时,您会得到fieldcount被关闭的结果,因为这是不可能的,因为您需要读取这些数据,请在关闭using之前先读取它们,或者您可以手动打开和关闭连接,而不使用(using)语句。


同意。 "using (_connection) {" 是在您“使用”数据读取器之前关闭数据读取器的内容。删除“using”,保留“CommandBehavior.CloseConnection”,并在使用完数据读取器后确保调用.Close()。 - granadaCoder

2
您的代码显示正常。我已将其放入测试项目中并且它可以正常工作。目前还不清楚为什么您会在上面显示的代码中收到此消息。以下是一些调试提示/建议,希望对您有所帮助。
  • while (dataReader.Read())上创建一个断点。在进入其代码块之前,在您的Immediate或Watch窗口中输入以下内容:dataReader.HasRows。这应该评估为true。

  • 当停留在Read()上时,打开本地窗口以检查dataReader的所有属性。确保FieldCount与您的SELECT语句期望的相同。

  • 当进入此Read()迭代时,是否创建了一个学生对象?Immediate Window中的dataReader["StructureID"]和其他所有值是多少?

CommandBehavior.CloseConnection不是造成问题的原因。它只是告诉连接在关闭数据读取器时也关闭自身。

1
你是对的,问题不在于CommandBehavior.CloseConnection。这掩盖了真正的问题——试图将数据类型转换为错误的内容。只有当我逐步执行代码时才会出现“尝试在读取器关闭时调用FieldCount无效”的错误(也许是因为我花费了太长时间?)。 - ClareBear
是的,这是数据类型问题。数据库中的数据类型是datetime2,而在源代码中我将此字段引用为字符串。因此,在获取之前,我必须将数据库中的datetime2字段强制转换为varchar(11)。 - Krishna

1
当我遇到那个错误时,它恰好是一个命令超时问题(我正在读取一些大型二进制数据)。作为第一次尝试,我增加了命令超时时间(而不是连接超时时间!),问题得到了解决。 注意:在尝试查找问题时,我试图监听(Sql)连接的StateChanged事件,但事实证明该连接从未处于“断开”状态。

1

我也遇到了同样的问题。测试了上述所有解决方案

  • 增加命令超时时间
  • 读取后关闭连接

以下是代码

    1 objCmd.Connection.Open()
    2 objCmd.CommandTimeout = 3000
    3 Dim objReader As OleDbDataReader = objCmd.ExecuteReader()
    4 repeater.DataSource = objReader
    5 CType(repeater, Control).DataBind()
    6 objReader.Close()
    7 objCmd.Connection.Dispose()

此外,在第4行,objReader 的 Closed 属性为 False。

0

在使用VS.NET调试器并尝试检查一些IQueryable结果时,我遇到了这个异常。这是一个糟糕的决定,因为IQueryable导致了大量的表扫描。停止并重新启动调试器,并且不尝试预览这个特定的IQueryable是解决方法。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接