C# 已存在与此命令关联的打开的DataReader,但没有嵌套的DataReader

C# 已存在与此命令关联的打开的DataReader,但没有嵌套的DataReader,c#,asp.net,ado.net,database-connection,C#,Asp.net,Ado.net,Database Connection,我间歇性地出现以下错误。 已存在与此命令关联的打开的DataReader,必须先关闭该命令 我了解到,当同一连接中存在嵌套的DataReader时,可能会发生这种情况,但在我的例子中,我使用以下代码来执行所有查询 private SqlTransaction Transaction { get; set; } private SqlConnection Connection { get; set; } private DbRow Row {get; set;}

我间歇性地出现以下错误。 已存在与此命令关联的打开的DataReader,必须先关闭该命令

我了解到,当同一连接中存在嵌套的DataReader时,可能会发生这种情况,但在我的例子中,我使用以下代码来执行所有查询

    private SqlTransaction Transaction { get; set; }
    private SqlConnection Connection { get; set; }
    private DbRow Row {get; set;}

    public Row Exec(string sql){
        try{
            //Begin connection/transaction
            Connection = new SqlConnection(connectionString);
            Connection.Open();
            Transaction = Connection.BeginTransaction("SampleTransaction");  

            //create command
            SqlCommand command = new SqlCommand(sql, Connection);
            command.Transaction = Transaction;

            //execute reader and close it
            //HERE IS THE PROBLEM, THE READER ALWAYS READ UNTIL THE END
            //BEFORE ANOTHER CAN BE OPENED
            reader = command.ExecuteReader();                
            while (reader.Read())
            {
                object[] value = new object[reader.FieldCount];
                reader.GetValues(value);
                List<object> values = new List<object>(value);                    
                Rows.Add(values);
            }                
            reader.Close();
            Transaction.Commit();
            Connection.Dispose();
            Connection = null;
        }
        catch
        {
           Transaction.Rollback();
           Connection.Dispose();
           Connection = null;
        }
        finally
        {
            if (reader != null && !reader.IsClosed) reader.Close();
        }
    }

因为这种情况只发生在生产环境中,所以bug很可能在您附加的代码之外

防止这种情况的最常见方法是始终以以下方式编写代码:

reader = command.ExecuteReader();
try
{
        for (int i = 0; i < reader.FieldCount; i++)
        {
            dbResult.Columns.Add(reader.GetName(i));
            dbResult.Types.Add(reader.GetDataTypeName(i));
        }
        while (reader.Read())
        {
            object[] value = new object[reader.FieldCount];
            reader.GetValues(value);
            List<object> values = new List<object>(value);                    
            Rows.Add(values);
        }                            
}
finally
{
    reader.Close();
}
reader=command.ExecuteReader();
尝试
{
对于(int i=0;i
请注意
finally
块,它确保读卡器在任何情况下都处于关闭状态。我的印象是,您的代码中发生了一些让读者无法阅读的事情,但在您发布的代码中却看不到该bug

我建议您将其包含在上面的try/finally块中,您的错误很可能会得到解决


编辑,澄清一下:这可能无法解决最初显示的代码范围之外存在的任何错误,但它将阻止数据读取器保持打开状态。最后,我建议的
块不会阻止任何异常,它们将被传播到您在它之外使用的任何处理程序。

因为这种情况只发生在生产中,所以bug很可能在您附加的代码之外

防止这种情况的最常见方法是始终以以下方式编写代码:

reader = command.ExecuteReader();
try
{
        for (int i = 0; i < reader.FieldCount; i++)
        {
            dbResult.Columns.Add(reader.GetName(i));
            dbResult.Types.Add(reader.GetDataTypeName(i));
        }
        while (reader.Read())
        {
            object[] value = new object[reader.FieldCount];
            reader.GetValues(value);
            List<object> values = new List<object>(value);                    
            Rows.Add(values);
        }                            
}
finally
{
    reader.Close();
}
reader=command.ExecuteReader();
尝试
{
对于(int i=0;i
请注意
finally
块,它确保读卡器在任何情况下都处于关闭状态。我的印象是,您的代码中发生了一些让读者无法阅读的事情,但在您发布的代码中却看不到该bug

我建议您将其包含在上面的try/finally块中,您的错误很可能会得到解决


编辑,澄清一下:这可能无法解决最初显示的代码范围之外存在的任何错误,但它将阻止数据读取器保持打开状态。最后,我建议的
块不会阻止任何异常,它们将被传播到您在它之外使用的任何处理程序。

因为这种情况只发生在生产中,所以bug很可能在您附加的代码之外

防止这种情况的最常见方法是始终以以下方式编写代码:

reader = command.ExecuteReader();
try
{
        for (int i = 0; i < reader.FieldCount; i++)
        {
            dbResult.Columns.Add(reader.GetName(i));
            dbResult.Types.Add(reader.GetDataTypeName(i));
        }
        while (reader.Read())
        {
            object[] value = new object[reader.FieldCount];
            reader.GetValues(value);
            List<object> values = new List<object>(value);                    
            Rows.Add(values);
        }                            
}
finally
{
    reader.Close();
}
reader=command.ExecuteReader();
尝试
{
对于(int i=0;i
请注意
finally
块,它确保读卡器在任何情况下都处于关闭状态。我的印象是,您的代码中发生了一些让读者无法阅读的事情,但在您发布的代码中却看不到该bug

我建议您将其包含在上面的try/finally块中,您的错误很可能会得到解决


编辑,澄清一下:这可能无法解决最初显示的代码范围之外存在的任何错误,但它将阻止数据读取器保持打开状态。最后,我建议的
块不会阻止任何异常,它们将被传播到您在它之外使用的任何处理程序。

因为这种情况只发生在生产中,所以bug很可能在您附加的代码之外

防止这种情况的最常见方法是始终以以下方式编写代码:

reader = command.ExecuteReader();
try
{
        for (int i = 0; i < reader.FieldCount; i++)
        {
            dbResult.Columns.Add(reader.GetName(i));
            dbResult.Types.Add(reader.GetDataTypeName(i));
        }
        while (reader.Read())
        {
            object[] value = new object[reader.FieldCount];
            reader.GetValues(value);
            List<object> values = new List<object>(value);                    
            Rows.Add(values);
        }                            
}
finally
{
    reader.Close();
}
reader=command.ExecuteReader();
尝试
{
对于(int i=0;i
请注意
finally
块,它确保读卡器在任何情况下都处于关闭状态。我的印象是,您的代码中发生了一些让读者无法阅读的事情,但在您发布的代码中却看不到该bug

我建议您将其包含在上面的try/finally块中,您的错误很可能会得到解决


编辑,澄清一下:这可能无法解决最初显示的代码范围之外存在的任何错误,但它将阻止数据读取器保持打开状态。我建议的
最后
块不会阻止任何异常,它们将传播到您在其外部使用的任何处理程序。

问题是,当查询失败时,事务无法回滚,因为数据读取器已在运行