проблема сохранения базы данных c # из ListView

#c#

#c#

Вопрос:

У меня есть ListView. В нем 6 столбцов:

 question_id | question_text | start_time | end_time | status | repeat 
  

соответственно. Прямо сейчас я могу отображать данные из базы данных. Это мой код:

 private void Voting_Editor_Tool_Load(object sender, EventArgs e)
{
    GetData();
}

public void GetData()
{
    try
    {
        now = DateTime.Now;
        String time_date = now.ToString();
        myConnection = new SqlConnection(@"User ID=sa;Password=password123;Initial Catalog=dishtv;Persist Security Info=True;Data Source=ENMEDIA-EA6278EENMEDIA");
        //myConnection.Open();
        //SqlDataReader dr = new SqlCommand("SELECT question_text,question_id FROM otvtbl_question ", myConnection).ExecuteReader();

        // listView1.Columns.Clear();
        listView1.Items.Clear();

        myConnection.Open();
        String MyString1 = string.Format("SELECT question_id,question_text,start_time,end_time,status,repeat FROM otvtbl_question");

        com = myConnection.CreateCommand();
        com.CommandText = MyString1;

        dr = com.ExecuteReader();
        ListViewItem itmX;
        //Adding the Items To The Each Column
        while (dr.Read())
        {
            itmX = new ListViewItem();
            itmX.Text = dr.GetValue(0).ToString();
             var word = itmX.Text;
            for (int i = 1; i < 6; i  )
            {
                itmX.SubItems.Add(dr.GetValue(i).ToString());
            }
            if (dr.GetDateTime(2) < now amp;amp; dr.GetDateTime(3) > now)
            {
                itmX.SubItems[4].Text = "Broadcasting";
            }
            else if (dr.GetDateTime(3) < now)
            {
                string a=Convert.toString(dr.GetDateTime(3));
                itmX.SubItems[4].Text = "Expired";
                String broadcast = string.Format("UPDATE otvtbl_question SET             status='EXPIRED' where start_time='{6}'",a );
                //Execute the SqlCommand
                com = new SqlCommand(broadcast, myConnection);
                com.ExecuteNonQuery();
            }
            else
            {
                itmX.SubItems[4].Text = "Not Expired";
            }
            listView1.Items.Add(itmX);
        }

        dr.Close();
        myConnection.Close();
    }
    catch (Exception ex)
    {
        //Error Message While Fetching
        MessageBox.Show("Error While Fetching the data From the DataBase"   ex);
    }
    finally
    {
        //Closing The Connection
        if (dr != null)
            dr.Close();

        if (myConnection.State == ConnectionState.Open)
            myConnection.Close();

    }
}
  

В этом коде столбец состояния должен обновляться каждый раз, когда пользователь загружает форму. Во время загрузки формы она должна проверить, больше ли start_time текущего времени. Если оно больше, чем должно отображаться в столбце status, NOT EXPIRED в противном случае оно должно отображаться EXPIRED . Проблема в том, что я могу отобразить EXPIRED и NOT EXPIRED значения в Status столбце путем сравнения времени, но я хочу сохранить EXPIRED и NOT EXPIRED значения в базе данных, пока она отображает значения в столбце состояния. Я попытался обновить ее, используя следующую команду:

 String broadcast = string.Format("UPDATE otvtbl_question SET                status='EXPIRED' where start_time='{6}'",a );
//Execute the SqlCommand
com = new SqlCommand(broadcast, myConnection);
com.ExecuteNonQuery();
  

Но в нем говорится:

DataReader необходимо закрыть перед обновлением данных.

Я даже пытался закрыть datareader и попытался обновить, и он выдает разные ошибки как:

Индекс (основанный на нуле) должен быть больше или равен нулю и меньше размера списка аргументов

Есть предложения?

Комментарии:

1. Не должен ли ваш запрос на обновление содержать в качестве поля параметра {0} вместо {6}?

Ответ №1:

Вы должны реализовать инструкцию using. Это решит проблему. Ниже приведены блоки, в которых должна быть реализована инструкция using.

  1. Подключение к Sql
  2. DataReader

Кроме того, мы должны использовать параметризованные запросы. Ниже приведен пример кода.

 using (System.Data.SqlClient.SqlConnection con = new SqlConnection("YourConnection string")) { 
    con.Open(); 
    SqlCommand cmd = new SqlCommand(); 
    string expression = "Parameter value"; 
    cmd.CommandType = CommandType.StoredProcedure; 
    cmd.CommandText = "Your Stored Procedure"; 
    cmd.Parameters.Add("Your Parameter Name", 
                SqlDbType.VarChar).Value = expression;    
    cmd.Connection = con; 
    using (IDataReader dr = cmd.ExecuteReader()) 
    { 
        if (dr.Read()) 
        { 
        } 
    } 
}
  

Вот пример IDisposable, запрошенный вами.
IDisposable

Комментарии:

1. показывает ошибку 1 Локальная переменная с именем ‘dr’ не может быть объявлена в этой области, потому что это придало бы другое значение ‘dr’, которое уже используется в ‘родительской или текущей’ области для обозначения чего-то другого.

2. Не показываю свою сторону. Не могли бы вы поделиться обновленным кодом в запросе, пожалуйста?

3. Я думаю, вы объявили это дважды выше инструкции using. итак, если вы можете, пожалуйста, поделиться кодом в запросе?

4. Спасибо за вашу помощь. Я решил. Я добавил «MultipleActiveResultSets = true» в sqlconnection как для чтения, так и для вставки в базу данных.

5. Это здорово. Но я бы рекомендовал использовать инструкции «Using», где IDisposable наследуется для класса. Это приведет к автоматическому удалению объекта и также позволит избежать утечек памяти