我想要的是INSERT
在 C# 中做一个简单的,但我目前得到这个错误:
已经有一个打开的 DataReader 与此 Connection 关联,必须先关闭它。
要插入的代码:
string QueryCon = "SELECT Id_Categoria FROM Categoria where Nombre='" + Categoria + "'";
connection.Close();
connection.Open();
MySqlCommand ConnCombo = new MySqlCommand(QueryCon, connection);
MySqlDataReader reader = ConnCombo.ExecuteReader();
while (reader.Read())
{
Id_C = int.Parse(reader.GetString("Id_Categoria"));
}
string query = "INSERT INTO compra (Articulo, Categoria,Importancia,Obligatorio,Costo,Descripcion,Adquirir) VALUES('" + Articulo + "', '" + Id_C + "'," + Importancia + ",'no'," + Costo + ",'" + Descripcion + "','No','" + Mes + "')";
if (aprobar==true) {
//create command and assign the query and connection from the constructor
MySqlCommand cmd = new MySqlCommand(query, connection);
//Execute command
cmd.ExecuteNonQuery(); ------- Error
connection.Close();
}
您的问题的答案与您发送的错误相同。它说,由于您已经有一个打开的阅读器,在您关闭它之前您不能做任何其他事情。如果您想并行处理,您应该打开另一个连接。
如果没有,
reader.Close()
请在完成使用它之后再做。发生错误是因为您
reader
在运行insert
.using
为避免此类问题,养成为实现接口的此类对象使用块的习惯非常重要IDisposable
:仅仅执行
.Close()
是不够的,因为如果抛出异常,仍然有可能让数据读取器保持打开状态。通过使用 blockusing
,您可以保证在退出 block 时资源将被关闭。此外,在更正的代码中,我故意避免包含处理连接的代码,因为我不同意。我不知道为什么人们普遍迷恋全局连接,但这非常危险,并且如果您碰巧转移到多线程环境,也可能导致您收到错误以及其他错误。每次需要与数据库通信时最好获取一个单独的连接实例,然后立即关闭它。通常,ADO.NET 提供程序会在您甚至没有意识到的情况下处理连接池,因此您不会每次都真正打开和关闭连接,并且性能很好。
所以如果你想避免问题,代码实际上应该是这样的:
最后,补充一点,因为我之前没有意识到这一点:在构造查询时使用参数非常重要。永远不要在你的 SQL 中直接连接值。除了 SQL 注入安全问题(我可以理解您可能不太关心取决于您使用的项目类型)之外,它还可以让您避免出现未转义引号的问题,帮助服务器提高性能等等。养成这个好习惯非常重要。