我遇到一个错误,说我的数据读取器已经打开。
我的代码看起来像这样
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命令已打开。的确如此,但是如何使用阅读器中的信息调用Role.GetRoleByID。
我在C#和ASP.NET中编码
最佳答案
您的Role.GetRoleByID
似乎将尝试重用连接。
选项:
从SqlDataReader
内的GetByID
中获取所需的数据,关闭该读取器,然后调用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
所需的联接?那意味着您只需要一趟数据库。关于c# - DataReader已打开,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8952331/