При использовании MySqlDataReader произошла фатальная ошибка
Я получаю следующую ошибку в моем приложении C# WinForms:
фатальная ошибка при чтении данных
я использую mysql.data V4.0.30319
,
Вот мой код:
int catCount = 1;
while (catCount < 13)
{
MySqlConnection con = new MySqlConnection("server=server;user id=user;password=password;database=db;");
con.Open();
MySqlDataReader Rd;
string query = "SELECT oc_newsletter_old_system.email FROM oc_newsletter_old_system WHERE oc_newsletter_old_system.cat_uid = " + catCount;
MySqlCommand mC = new MySqlCommand(query, con);
Rd = mC.ExecuteReader();
try
{
while (Rd.Read())
{
string email = Rd.GetString(0);
Boolean insert = true;
int realCat = 0;
switch (catCount)
{
case '1':
fileBrian += email + "\r\n";
break;
case '2':
fileDunamis += email + "\r\n";
break;
case '3':
fileFrohlich += email + "\r\n";
break;
case '4':
fileGaithers += email + "\r\n";
break;
case '5':
fileGospel7 += email + "\r\n";
break;
case '6':
fileLifeshop += email + "\r\n";
realCat = 1;
break;
case '7':
fileMeyer += email + "\r\n";
break;
case '8':
fileOpwekking += email + "\r\n";
break;
case '9':
filePelgrimKerken += email + "\r\n";
realCat = 2;
break;
case 10:
filePelgrimKlanten += email + "\r\n";
realCat = 2;
break;
case 11:
filePelgrimPers += email + "\r\n";
insert = false;
break;
case 12:
filePelgrimScholen += email + "\r\n";
insert = false;
break;
}
if (insert == true)
{
string salt = "h1bsqnp6wyxjxhf29ziuwsihg8nixe05";
byte[] asciiBytes = ASCIIEncoding.ASCII.GetBytes(salt + email);
byte[] hashedBytes = MD5CryptoServiceProvider.Create().ComputeHash(asciiBytes);
string hashedString = BitConverter.ToString(hashedBytes).Replace("-", "").ToLower();
string query2 = "INSERT IGNORE INTO `oc_ne_marketing` (`email`,`code`, `subscribed`, `store_id`) VALUES ('" + email + "', '" + hashedString + "', '1', '" + realCat + "')";
MySqlConnection connection = new MySqlConnection("server=server;user id=user;password=password;database=db;");
connection.Open();
try
{
MySqlCommand cmd1 = new MySqlCommand(query2, connection);
cmd1.CommandText = query2;
cmd1.ExecuteNonQuery();
cmd1.Dispose();
}
finally
{
connection.Close();
}
}
Application.DoEvents();
}
}
finally
{
Rd.Close();
con.Close();
}
catCount++;
progressBar1.PerformStep();
progressBar1.Refresh();
Application.DoEvents();
}
Я получаю сообщение об ошибке в этой строке:
while (Rd.Read())
Единственное, что я обнаружил, так это проблема закрытия ридера и соединения, но, насколько я знаю, все в порядке...
Так вы, ребята, поняли, в чем дело???
2 ответа
А2А, ради полноты.
Обходной путь тогда должен был настроить параметры net_xxx_timeout. Например, выполните следующее после открытия соединения и перед запуском устройства чтения данных:
var c = new MySqlCommand("set net_write_timeout=99999; set net_read_timeout=99999", con);
c.ExecuteNonQuery();
Вот источник из MySql.Data
в классе соединения:
protected override void Dispose(bool disposing)
{
if (State == ConnectionState.Open)
Close();
base.Dispose(disposing);
}
что, в основном, означает, что утилизации достаточно, чтобы закрыть его (иначе это странно). То же самое относится и к SqlConnection
тоже..
Хотя это и не прямой ответ на вашу проблему, но по вашему запросу здесь есть некоторая информация и пример кода на using
,
Это общепринятая лучшая практика для использования using
заявления с объектами, которые реализуют IDisposable
- по сути, он делает то же самое, что и блок try/finally.
После выхода из области применения using (либо операция завершается, либо выдается исключение), Dispose
будет вызван на объекте. Смотрите использование Statement для более подробной информации.
Вот сокращенный пример, основанный на вашем коде:
int catCount = 1;
string connectionString = "server=server;user id=user;password=password;database=db;"
string query = "SELECT email FROM oc_newsletter_old_system WHERE cat_uid=@cat_uid";
while (catCount < 13)
{
using (MySqlConnection con = new MySqlConnection(connectionString))
{
con.Open();
MySqlCommand mC = new MySqlCommand(query, con);
mC.Parameters.AddWithValue("@cat_uid", catCount);
using (MySqlDataReader Rd = mC.ExecuteReader())
{
while (Rd.Read())
{
// rest of your code here
}
}
}
}
Обратите внимание, что вышеприведенное основано на классах.NET SqlConnection, SqlCommand и SqlDataReader, но должно быть одинаковым (или очень похожим) для MySql.
Я переместил строку подключения и строку запроса в их собственные переменные (но это личное предпочтение). Я также привел пример того, как делать параметризованные запросы (mCParameters.AddWithValue
Линия - привыкание использовать парметеризованные запросы (IMO) - хорошая вещь, особенно если вы переходите от WinForms к веб-приложениям, так как это предотвращает атаки SQL-инъекций.