C# 当读卡器关闭时调用Read的尝试无效。(C)
我创建了一个从表中获取数据的方法,但它给出了标题中所述的错误。在这里发帖之前,我已经阅读了包括stackoverflow在内的各种网站的许多方法,但这对我没有帮助 下面是我的方法C# 当读卡器关闭时调用Read的尝试无效。(C),c#,sql,sql-server,C#,Sql,Sql Server,我创建了一个从表中获取数据的方法,但它给出了标题中所述的错误。在这里发帖之前,我已经阅读了包括stackoverflow在内的各种网站的许多方法,但这对我没有帮助 下面是我的方法 public SqlDataReader GetCustomer() { SqlDataReader reader = null; _conn = new SqlConnection(connString); string sqlQuery = @"SEL
public SqlDataReader GetCustomer()
{
SqlDataReader reader = null;
_conn = new SqlConnection(connString);
string sqlQuery = @"SELECT CustName, CustNationality FROM Customer";
using (_conn)
{
using (SqlCommand cmd = new SqlCommand(sqlQuery, _conn))
{
_conn.Open();
reader = cmd.ExecuteReader();
_conn.Close();
}
}
return reader;
}
我把这个方法称为
SqlDataReader reader = null;
cmboBoxClient.Items.Add("");
reader = connect.GetCustomer() as SqlDataReader;
while (reader.Read())
{
cmboBoxClient.Items.Add(reader["CustName"] + " " + reader["CustNationality"]);
}
但是给了我错误,我尝试了IEnumerable方法,但是它给了我转换/强制转换的错误。i、 将IDataReader转换为SqlDataReader。
后来我读到这种方法是不可能的
请建议我。当您关闭连接时,读卡器将不再有效 在关闭连接和处理命令之前,可以将读取逻辑移动到另一个方法(即GetCustomer)中的循环中 另一种解决方案是使用如下回调:
public void GetCustomer(Action<SqlDataReader> callback)
{
var connString = "connection_string";
SqlDataReader reader = null;
var _conn = new SqlConnection(connString);
string sqlQuery = @"SELECT CustName, CustNationality FROM Customer";
using (_conn)
{
using (SqlCommand cmd = new SqlCommand(sqlQuery, _conn))
{
_conn.Open();
using(reader = cmd.ExecuteReader())
{
callback(reader);
}
}
}
}
connect.GetCustomer((reader =>
{
while (reader.Read())
{
cmboBoxClient.Items.Add(reader["CustName"] + " " + reader["CustNationality"]);
}
}));
这允许您使GetCustomer方法更通用。您可以多次重复使用它,每次都可以以不同的方式使用读卡器
您可能希望为该方法使用更好的名称。例如,ReadCustomers。当您关闭连接时,读卡器不再有效 在关闭连接和处理命令之前,可以将读取逻辑移动到另一个方法(即GetCustomer)中的循环中 另一种解决方案是使用如下回调:
public void GetCustomer(Action<SqlDataReader> callback)
{
var connString = "connection_string";
SqlDataReader reader = null;
var _conn = new SqlConnection(connString);
string sqlQuery = @"SELECT CustName, CustNationality FROM Customer";
using (_conn)
{
using (SqlCommand cmd = new SqlCommand(sqlQuery, _conn))
{
_conn.Open();
using(reader = cmd.ExecuteReader())
{
callback(reader);
}
}
}
}
connect.GetCustomer((reader =>
{
while (reader.Read())
{
cmboBoxClient.Items.Add(reader["CustName"] + " " + reader["CustNationality"]);
}
}));
这允许您使GetCustomer方法更通用。您可以多次重复使用它,每次都可以以不同的方式使用读卡器
您可能希望为该方法使用更好的名称。例如,ReadCustomers。在返回reader之前,您正在关闭连接。在使用数据库游标时,应保持连接打开。所以,返回读取器并不是最好的选择,因为在调用方使用连接时,您无法处理该连接。我建议您创建强类型类Customer 并在GetCustomers方法中填写客户列表是的,您的查询返回多个客户,而不是单个客户:
public IEnumerable<Customer> GetCustomers()
{
string sqlQuery = @"SELECT CustName, CustNationality FROM Customer";
using (var conn = new SqlConnection(connString))
using (SqlCommand cmd = new SqlCommand(sqlQuery, conn))
{
conn.Open();
var reader = cmd.ExecuteReader();
while(reader.Read())
{
yield return new Customer {
Name = (string)reader["CustName"],
Nationality = (string)reader["CustNationality"]
};
}
}
}
顺便说一句,你可以做所有的查询和映射。所以代码看起来像
public IEnumerable<Customer> GetCustomers()
{
using (var conn = new SqlConnection(connString))
{
conn.Open();
return conn.Query<Customer>("SELECT CustName, CustNationality FROM Customer");
}
}
是的,这就是您所需要的。在返回读卡器之前,您正在关闭连接。在使用数据库游标时,应保持连接打开。所以,返回读取器并不是最好的选择,因为在调用方使用连接时,您无法处理该连接。我建议您创建强类型类Customer 并在GetCustomers方法中填写客户列表是的,您的查询返回多个客户,而不是单个客户:
public IEnumerable<Customer> GetCustomers()
{
string sqlQuery = @"SELECT CustName, CustNationality FROM Customer";
using (var conn = new SqlConnection(connString))
using (SqlCommand cmd = new SqlCommand(sqlQuery, conn))
{
conn.Open();
var reader = cmd.ExecuteReader();
while(reader.Read())
{
yield return new Customer {
Name = (string)reader["CustName"],
Nationality = (string)reader["CustNationality"]
};
}
}
}
顺便说一句,你可以做所有的查询和映射。所以代码看起来像
public IEnumerable<Customer> GetCustomers()
{
using (var conn = new SqlConnection(connString))
{
conn.Open();
return conn.Query<Customer>("SELECT CustName, CustNationality FROM Customer");
}
}
是的,这就是您所需要的。从GetCustomer方法返回customer实例,而不是从GetCustomer方法返回readerReturn customer实例,而不是返回Reader,因为在调用方使用连接时无法处理连接,是的,您可以,如果在处理读取器时执行cmd.ExecuteReaderCommandBehavior.CloseConnection,则会关闭基础连接。虽然没有处理连接,但处理连接所做的唯一一件事就是关闭连接,并将几个内部变量调零。这是错误OP的解释——目前,他在调用方使用连接时关闭连接。但无论如何,感谢您指向CommandBehavior选项,抱歉,误解了该语句。因为您无法在调用方使用连接时释放连接,所以可以,如果您执行cmd.ExecuteReaderCommandBehavior.CloseConnection,则在释放读卡器时关闭基础连接。虽然没有处理连接,但处理连接所做的唯一一件事就是关闭连接,并将几个内部变量调零。这是错误OP的解释——目前,他在调用方使用连接时关闭连接。但不管怎样,谢谢你指出命令行为选项啊,对不起,误解了声明。