DataReader已经打开

时间:2012-01-21 10:38:09

标签: c# asp.net .net datareader

我遇到一个错误,说我的datareader已经打开了。

我的代码看起来像这样

public static Users GetByID(int ID, SqlConnection connection)
    {
        SqlCommand command = new SqlCommand("Select Name, Email, LastLogin, FK_Role_ID from Users where ID=@id");
        command.Connection = connection;

        command.Parameters.Add(new SqlParameter("id", ID));

        SqlDataReader reader = command.ExecuteReader();
        if (reader.Read())
        {
            Users user = new Users();
            user.ID = ID;
            user.Name = reader.GetString(0);
            user.Email = reader.GetString(1);
            user.LastLogin = reader.GetString(2);
            user.role = Role.GetRoleByID(reader.GetInt32(3), connection);
            reader.Close();
            return user;
        }
        else
        {
            reader.Close();
            return null;
        }
    }

Role.GetRoleByID中出现错误,表示datareader命令是alreader open。这是真的,但我如何使用读者的信息调用Role.GetRoleByID。

我在c#和ASP.NET中编码

3 个答案:

答案 0 :(得分:4)

您的Role.GetRoleByID似乎会尝试重复使用该连接。

选项:

  • SqlDataReaderGetByID获取所需数据,关闭该读卡器,然后调用Role.GetRoleByID(因此您只有一个活跃的读者一次)
  • 启用多个活动结果集(MARS) - 我不能说我对此有任何经验
  • 使每个方法使用单独的连接来减少方法之间的依赖关系。请注意,连接池将使开/关合理便宜。

如果我是你,我会选择第一个选项 - 或者可能是最后一个选项。我还会使用using语句自动关闭阅读器:

private const string GetUserByIdSql =
    "Select Name, Email, LastLogin, FK_Role_ID from Users where ID=@id";

public static Users GetByID(int ID, SqlConnection connection)
{
    var sql = ;
    Users user;
    int roleId;
    using (var command = new SqlCommand(GetUserByIdSql, connection))
    {
        command.Parameters.Add(new SqlParameter("id", ID));
        using (var reader = command.ExecuteReader())
        {
            if (!reader.Read())
            {
                return null;
            }
            user = new Users
            {
                Name = reader.GetString(0),
                Email = reader.GetString(1),
                LastLogin = reader.GetString(2),
            };
            // Remember this so we can call GetRoleByID after closing the reader
            roleID = reader.GetInt32(3);
        }
    }
    user.Role = Role.GetRoleByID(roleID, connection);
    return user;
}

作为第四个选项 - 为什么不在现有查询中执行GetRoleByID所需的加入?这意味着你只需要一次数据库之旅。

答案 1 :(得分:2)

您可以考虑使用带有必需连接的Select查询,以便能够从同一查询中接收角色。

此外,建议使用(using reader = command.ExecuteReader() ),以便在范围结束后关闭阅读器并进行处理。

答案 2 :(得分:1)

您是否允许MARS连接字符串(MultipleActiveResultSets=true)?