2015-07-01 4 views
1

В этом разделе есть несколько учебников, но я предполагаю, что я должен был внедрить что-то неправильно, потому что код, который я использовал из комбинированных руководств, не работает должным образом.Обновление базы данных SQL из DataGridView в C#

Эти учебные пособия: https://youtu.be/_i4mYXSaD4w, https://youtu.be/_sB0A6FIhUM

Я пытаюсь создать DataGridView, который отображает основные данные, только 4 колонки информации. Я хочу, чтобы пользователь мог добавлять, обновлять и удалять строки информации. Я вручную создал 1 строку информации в базе данных SQL, чтобы избежать «уловов» при загрузке программы.

У меня есть 1 строка моей базы данных базы данных SQL, которая просто прекрасна, но когда я редактирую эту информацию и нажимаю кнопку обновления, она, похоже, не работает на стороне SQL, хотя программа работает , Под этим я подразумеваю, что у меня есть сообщение, подтверждающее его обновление, но когда я закрываю приложение и запускаю его снова, он загружает старые данные, и когда я дважды проверяю базу данных, он не обновлялся. Если кто-то может помочь мне отрегулировать это, когда я добавляю строки данных в DataGridView или редактирую строки, и на самом деле SQL-файл получает изменения/обновления, я был бы признателен. Вот мой код:

public partial class Form1 : Form 
{ 
    SqlConnection con; 
    SqlDataAdapter sda; 
    DataTable dt; 
    SqlCommandBuilder scb; 
    private int rowIndex = 0; 

    public Form1() 
    { 
     InitializeComponent(); 
    } 


    private void Form1_Load(object sender, EventArgs e) 
    { 
     try 
     { 
      con = new SqlConnection(Properties.Settings.Default.SchoolConnectionString); 
      con.Open(); 
      sda = new SqlDataAdapter("SELECT * FROM School", con); 
      dt = new DataTable(); 
      sda.Fill(dt); 
      dataGridView1.DataSource = dt; 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show("Error\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
     } 
    } 

    private void UpButton_Click(object sender, EventArgs e) 
    { 

     try 
     { 
      scb = new SqlCommandBuilder(sda); 
      sda.Update(dt); 
      MessageBox.Show("Information Updated", "Update", MessageBoxButtons.OK, MessageBoxIcon.Information); 
     } 

     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
     } 
    } 
    //button to refresh the data without need to close the app 
    private void RefButton_Click(object sender, EventArgs e) 
    { 
     try 
     { 
      con = new SqlConnection(Properties.Settings.Default.SchoolConnectionString); 
      con.Open(); 
      sda = new SqlDataAdapter("SELECT * FROM School", con); 
      dt = new DataTable(); 
      sda.Fill(dt); 
      dataGridView1.DataSource = dt; 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show("Error\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
     } 
    } 

    private void CloseButton_Click(object sender, EventArgs e) 
    { 
     Application.Exit(); 
    } 

    //BROKEN - supposed to bring up a menu item to delete the row 
    private void dataGridView1_CellMouseUp(object sender, DataGridViewCellMouseEventArgs e) 
    { 
     if (e.Button == MouseButtons.Right) 
     { 
      this.dataGridView1.Rows[e.RowIndex].Selected = true; 
      this.rowIndex = e.RowIndex; 
      this.dataGridView1.CurrentCell = this.dataGridView1.Rows[e.RowIndex].Cells[1]; 
      this.contextMenuStrip1.Show(this.dataGridView1, e.Location); 
      contextMenuStrip1.Show(Cursor.Position); 
     } 

    } 

    private void contextMenuStrip1_Click(object sender, CancelEventArgs e) 
    { 
     if (!this.dataGridView1.Rows[this.rowIndex].IsNewRow) 
     { 
      this.dataGridView1.Rows.RemoveAt(this.rowIndex); 
     } 
    } 


} 

Теперь, что я не уверен, что это одна вещь, которую я изменил от одного из учебных пособий, в том, что они использовали набор данных, а не DataTable, но, как я понимаю, другие чем набор данных, способный удерживать несколько структур таблиц, нет никаких различий в извлечении данных или их обновлении. Поскольку у меня не было кучи данных и разных таблиц, я чувствовал, что DataTable достаточно для моего использования этой программы.

Кроме того, в моей базе данных у меня есть первичный ключ, который представляет собой целое число и 4 столбца текста. Я бы предпочел избежать глупых столбцов целых чисел, таких как номера строк, и просто сделать свой первый текстовый столбец первичным ключом, но когда я пытаюсь это сделать и обновляю базу данных, он вызывает ошибки. Если есть способ сделать это, я буду благодарен за объяснение того, как, или если есть способ скрыть столбец первой строки, вытащить целочисленное значение для первичного ключа и заставить его автоматически увеличивать и/или корректировать это значение в соответствии с редактированием, изменениями и добавлением новых строк, что было бы здорово. Просто чтобы очистить, если я добавляю строки 2, 3 и 4, я хочу, чтобы эти значения были автогенерированы и просто сделали этот столбец невидимым. Как бы то ни было, мне нужно вручную ввести целое число.

Спасибо за любую помощь и совет.

Update # 1:

Итак, принимая некоторые рекомендации, я попытался с помощью DataSet в следующем формате:

private void Form1_Load(object sender, EventArgs e) 
    { 
     try 
     { 
      con = new SqlConnection(Properties.Settings.Default.SchoolConnectionString); 
      con.Open(); 
      sda = new SqlDataAdapter("SELECT * FROM School", con); 
      ds = new DataSet(); 
      sda.Fill(ds, "e"); 
      dataGridView1.DataSource = ds.Tables["e"]; 
      } 
     catch (Exception ex) 
     { 
      MessageBox.Show("Error\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
     } 
    } 

    private void UpButton_Click(object sender, EventArgs e) 
    { 

     try 
     { 
      scb = new SqlCommandBuilder(sda); 
      sda.Update(ds, "e"); 
      MessageBox.Show("Information Updated", "Update", MessageBoxButtons.OK, MessageBoxIcon.Information); 
     } 

     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
     } 
    } 

Я попытался с помощью DataTable снова в заданном формате в первой ответ при условии, используя следующий формат, но 2-мя способами: 1 без нового экземпляра SqlCommandBuilder, и один с: с:

private void Form1_Load(object sender, EventArgs e) 
    { 
     try 
     { 
      con = new SqlConnection(Properties.Settings.Default.SchoolConnectionString); 
      con.Open(); 
      sda = new SqlDataAdapter("SELECT * FROM School", con); 
      dt = new DataTable(); 
      sda.Fill(dt); 
      dataGridView1.DataSource = dt; 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show("Error\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
     } 
    } 

    private void UpButton_Click(object sender, EventArgs e) 
    { 

     try 
     { 
      scb = new SqlCommandBuilder(sda); 
      newDT = dt.GetChanges(); 
      if (newDT != null) 
      { 
       sda.Update(newDT); 
      } 
      MessageBox.Show("Information Updated", "Update", MessageBoxButtons.OK, MessageBoxIcon.Information); 
     } 

     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
     } 
    } 

WIT HOUT: В этой версии появляется сообщение об ошибке: «Обновление требует наличия обновленной команды UpdateCommand при передаче коллекции DataRow с измененными строками».

private void Form1_Load(object sender, EventArgs e) 
    { 
     try 
     { 
      con = new SqlConnection(Properties.Settings.Default.SchoolConnectionString); 
      con.Open(); 
      sda = new SqlDataAdapter("SELECT * FROM School", con); 
      dt = new DataTable(); 
      sda.Fill(dt); 
      dataGridView1.DataSource = dt; 
     } 
     catch (Exception ex) 
     { 
      MessageBox.Show("Error\n" + ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
     } 
    } 

    private void UpButton_Click(object sender, EventArgs e) 
    { 

     try 
     { 
      newDT = dt.GetChanges(); 
      if (newDT != null) 
      { 
       sda.Update(newDT); 
      } 
      MessageBox.Show("Information Updated", "Update", MessageBoxButtons.OK, MessageBoxIcon.Information); 
     } 

     catch (Exception ex) 
     { 
      MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
     } 
    } 

Sooooo, я в тупике. Все, кроме одного без SqlCommandBuilder, запускают обновленный Message Box, но ни один из них фактически не сохраняет изменения в базе данных sql.

ответ

0

Хорошо, спасибо больше Google и расчесывание через другие вопросы здесь, на этом сайте, я нашел, что кто-то ответил на аналогичный вопрос, который заставило меня понять, что на самом деле я пропустил что-то простое. Поэтому в случае, если кто-то другой сталкивается с этой проблемой, я думал, что поставил бы очень возможную аналогичную ошибку, которую я делал, что привело к этой проблеме.

Итак, я не понял, что Visual Studio создала временную версию моей базы данных в папке \ bin \ debug. (Если есть способ отключить эту функциональность, мне бы хотелось услышать об этом, потому что я думаю, что это довольно глупо) По какой-то причине, если вы откроете в Sever Explorer, чтобы найти ваш .mdf-файл, вручную добавив или удалив информация в этой базе данных отражается в программе при запуске, потому что она ищет этот файл, делает его копию и затем работает оттуда, пока вы используете приложение для тестирования. Неутешительный факт заключается в том, что (опять же, если я не пропустил, где это не произошло), он не перекосит эти изменения, внесенные вами во временную версию, в основной файл .mdf, который вы создали в первую очередь.

Так вот почему я не видел никаких изменений, потому что я смотрел на основной файл базы данных, где он фактически не работал. Как только я узнал, как найти временную версию из Visual Studio, и я запросил эту базу данных файлов, я действительно видел изменения. Для ясности несколько версий того, что я пробовал изначально, на самом деле работали.Таким образом, все решения, которые я пробовал выше, кроме тех, где я упоминал об этом, вызвали ошибку из-за отсутствия вызова SqlCommandBuilder, фактически обновляют временную базу данных.

В качестве побочного примечания, исходящего из Visual Studio, C#, перспективы новичка SQL, я удивлен обширными учебниками и информацией о SQL-базах данных и DataGridView, которые в процессе обучения не отмечены. Даже видеоролики Youtube, которые я смотрел, не сделали этого явным образом ясно, что, когда они «доказали», что обновления происходили, они не сделали очевидным, что они проверяли базу данных temp, а не основную.

0

Мне кажется, что вы никогда не устанавливаете инструкцию обновления SQL, а только выбираете утверждения.

Вам нужно добавить что-то в подобном:

sda.UpdateCommand = "UPDATE TABLE SET ..." 

Или создать новую DataAdapter/команду для обработки вашего обновления

После того, как вы, что на месте, вызывая обновление SDA должны работать.

После доработки:

Если бы это было, я бы использовал SqlCommand для обновления заявления.

private void UpButton_Click(object sender, EventArgs e) 
{ 

    try 
    { 
     using(con = new SqlConnection(Properties.Settings.Default.SchoolConnectionString)) 
     { 
      con.Open(); 
      string sqlCommand = "Update (Table) set [email protected] where [email protected]"; 
      SqlCommand cmd = new SqlCommand(sqlCommand, con); 
      cmd.Parameters.AddWithValue("@Value", updatedValue); 
      cmd.Parameters.AddWithValue("@ID", idOfRowToUpdate); 
      int rowsAffected = cmd.ExecuteNonQuery(); 
      if(rowsAffected == 1) 
      { 
       MessageBox.Show("Information Updated", "Update", MessageBoxButtons.OK, MessageBoxIcon.Information); 
      } 
      con.Close(); 
     } 
    } 
    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
    } 
} 

Things отметить:

Вам нужно будет получить значения вы обновляете с вашего стола и заменить его на UpdatedValue и idOfRowToUpdate.

Вам понадобится сформировать команду UPDATE для вашей таблицы.

«Использование» скобок помогает правильно избавиться от вашего объекта соединения.

Технически с использованием кронштейнов con.Close() не требуется. Я делаю это на всякий случай.

Revision # 2:

Хорошо, я сделал некоторые дополнительные исследования в SqlDataAdapter и как он функционирует в отношениях к DataTable, это выглядит гораздо проще, чем я думал.

Вы должны быть в состоянии отказаться в этом новом коде к методу UpButton_Click и его работы:

try 
    { 
     DataTable newDT = dt.GetChanges(); 
     if(newDT != null) 
     { 
      sda.Update(newDT); 
     } 
     MessageBox.Show("Information Updated", "Update", MessageBoxButtons.OK, MessageBoxIcon.Information); 
    } 

    catch (Exception ex) 
    { 
     MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); 
    } 

Согласно This StackOverflow Article, это должно быть все, что вам нужно сделать обновление.

+0

Не могли бы вы пересмотреть свой ответ, чтобы включить, как это будет сделано конкретно? Вероятно, я должен был четко прояснить, что я довольно новичок как для C#, так и для SQL. Кроме того, я не понимаю, что я видел, как код работал так, как я это делал, и он обновил базу данных SQL в учебнике пользователя youtube. Является ли тот факт, что он использовал DataSet? – TekGiant

+0

Извините, попросить более подробно, но где и как бы установить значения для «updatedValue и idOfRowToUpdate? Мне нужно сказать, чтобы он просто увеличивал количество бросков и вытаскивал значение в каждой строке и отправлял его для обновления таблицы, или есть способ проверить, изменилось ли значение с того, что изначально было загружено, а затем обновить только индекс информации в этой строке? Наконец, я попытался использовать DataSet вместо DataTable, потому что я нашел некоторые другие форумы и ссылки для людей, имеющих ту же самую проблему, и закодировал ее почти идентично мне, и другие люди сказали, что использование DataSet будет работать - это не так. – TekGiant

+0

Хорошо, поэтому я попробовал это по-разному, и это не сработало. Обновите основной вопрос, чтобы объяснить его более подробно. – TekGiant

Смежные вопросы