Эй, ребята, я перехожу с Java на C # теперь, когда я понял, что предпочитаю возможности языка C # по сравнению с Java, но у меня есть небольшая проблема.В MySQL, Connector / J и JDBC, я считаю, что одно из моих приложений позволяло выполнять несколько PreparedStatement
с, пока другое открыто, как я мог бы выполнить запрос, который возвращает ResultSet
, и пока ResultSet
все ещеоткрыть, я мог бы открыть еще один PreparedStatement
и получить еще один ResultSet
, или я мог бы просто выполнить обновление, основываясь на данных, которые я получил от моего первого ResultSet
(то есть вставить солт-значение и обновить столбец пароля с помощью SHA512хэш, когда я понимаю, что строка имеет открытый текст в столбце пароля).
Однако, с Connector / 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();
Если перемещение обновлениякод - единственная возможность, или, если она лучшая, я думаю, мне придется с этим справиться, но сначала я хочу получить больше идей о других возможностях, а затем выбрать вариант.