嘿,我正在从Java迁移到C#,现在我已经意识到我更喜欢C#语言特性而不是Java语言特性,但是我有这个小问题。在MySQL Connector/J和JDBC中,我相信我的一个应用程序允许在另一个打开时执行多个PreparedStatement
s,就像我可以执行返回ResultSet
的查询并且该ResultSet
仍然打开时,我可以打开另一个PreparedStatement
并得到另一个ResultSet
或者我可以执行一个更新,根据我从我的第一个ResultSet
得到的数据(即,插入一个salt值并用SHA512哈希更新密码列时,我意识到该行中有明文密码密码栏)。MySQL连接器/ NET连接每个连接多个DataReader?
然而,连接器/ NET,我已经认识到,每当我尝试这样做,我得到这个错误: MySql.Data.MySqlClient.MySqlException: There is already an open DataReader associated with this Connection which must be closed first.
有没有一种简单的方法来解决这个错误,也许的任何其他实现MySQL到.NET桥梁?我并不想在一个应用程序中创建很多数据库连接,尽管我可能想为应用程序中的每个线程创建一个(如在ThreadLocal中)。当我用两种不同的方法同时执行两个查询时,ThreadLocal DB连接将会有所帮助,但显然,我无法将这两个命令分离到不同的线程中,而且我也不想创建多余的线程。
顺便说一下,这里是代码本身。是的,我可以向下移动的更新代码后,我关闭了读者,但我有更多的类似的方法,其中一些更困难比这个来修复:
MySqlConnection con = DatabaseConnection.GetConnection();
MySqlCommand cmd = con.CreateCommand();
cmd.CommandText = "SELECT `id`,`password`,`salt`,`pin`,`gender`,`birthday` FROM `accounts` WHERE `name` = '" + AccountName + "'";
MySqlDataReader reader = cmd.ExecuteReader();
if (reader.Read())
{
AccountId = reader.GetInt32(0);
string passhash = !reader.IsDBNull(1) ? reader.GetString(1) : null;
string salt = !reader.IsDBNull(2) ? reader.GetString(2) : null;
m_pin = !reader.IsDBNull(3) ? reader.GetString(3) : null;
Gender = !reader.IsDBNull(4) ? reader.GetByte(4) : WvsCommon.Gender.UNDEFINED;
m_birthday = !reader.IsDBNull(5) ? reader.GetInt32(5) : 0;
if (!HashFunctions.HashEquals(pwd, HashAlgorithms.SHA512, passhash + salt))
{
if (passhash == pwd || salt == null && HashFunctions.HashEquals(pwd, HashAlgorithms.SHA1, passhash))
{
salt = HashFunctions.GenerateSalt();
passhash = HashFunctions.GenerateSaltedSha512Hash(pwd, salt);
MySqlCommand update = con.CreateCommand();
update.CommandText = "UPDATE `accounts` SET `password` = '" + passhash + "', `salt` = '" + salt + "' WHERE `id` = " + AccountId;
update.ExecuteNonQuery();
update.Dispose();
}
}
}
reader.Close();
cmd.Dispose();
如果移动的更新代码唯一的可能性,或者如果它是最好的,我想我必须做到这一点,但我想先获得关于其他可能性的更多想法,然后选择一个选项。
只是一个快速的新手问题,如果reader.Read()返回false,那么我们不必对它做一个reader.Close()? – 2010-09-12 15:56:20
@Kevin the Close会自动发生,因为读者的Dispose是用using语句调用的---这取决于你如何构造代码,你不需要明确地调用它。 – eglasius 2010-09-12 16:00:11
好的,谢谢!由于这一点,我想我对MySQL Connector/NET有了更好的理解。我想JDBC的ResultSet实际上只是一个存储所有数据的表,然后关闭PreparedStatement,以便其他查询和非查询可以在之后执行,这几乎是唯一的解释。 – 2010-09-12 16:24:55