2012-01-21 86 views
0

我遇到了一个错误,说我的数据读取器已经打开。DataReader已经打开

我的代码看起来像在Role.GetRoleByID这

public static Users GetByID(int ID, SqlConnection connection) 
    { 
     SqlCommand command = new SqlCommand("Select Name, Email, LastLogin, FK_Role_ID from Users where [email protected]"); 
     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; 
     } 
    } 

错误occours说,DataReader的命令是alreader开放。这是真的,但我如何使用来自我的阅读器的信息调用Role.GetRoleByID。在C#中

我的代码和ASP.NET

+0

你为什么不把GetRoleByID合并到你的查询中? –

回答

4

它看起来像你的Role.GetRoleByID将尝试重用连接。

选项:

  • 接你从内GetByIDSqlDataReader需要的数据,关闭该读卡器,然后呼叫Role.GetRoleByID(所以你只得到了一个积极的读者在同一时间)
  • 启用多个活动结果集(MARS) - 我不能说我有任何经验
  • 使每个方法使用单独的连接来减少方法之间的依赖关系。请注意,连接池将使开启/关闭合理便宜。

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

private const string GetUserByIdSql = 
    "Select Name, Email, LastLogin, FK_Role_ID from Users where [email protected]"; 

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所需的加入?这意味着你只需要一次访问数据库。

+0

+1使用语句 – CodeZombie

+0

在我的代码中,如果读者没有阅读,则返回null是后备。在上面的代码中,返回用户是一个制造者,即使读者没有阅读。这将如何影响空结果? –

+1

@MichaelTotKorsgaard:再看一遍:if(!reader.Read()){return null; }' –

1

你允许MARS连接字符串(MultipleActiveResultSets=true)吗?

1

您可以考虑使用具有必要连接的Select查询,以便能够从相同查询接收角色。

此外,建议使用(using reader = command.ExecuteReader()),以便读者关闭并在示波器结束后立即处置。

相关问题