嘿,我正在從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