none
Проблема с DataGridView RRS feed

  • Вопрос

  • Привет.

    В общем у меня такая проблема - в гриде отображаются данные из таблицы БД. При попытке сохранить измененные данные:

    try
                {
                    this.Validate();
                    this.abiturientiBindingSource.EndEdit();
                    this.abiturientiTableAdapter.Update(this.insboardDataSet.abiturienti);
                    MessageBox.Show("Update successful");
                }
                catch (System.Exception ex)
                {
                    MessageBox.Show("Update failed");

    Еще до блока try возникает исключение датагрида:

    Да, ключевое поле idabiturienta у меня UNIQUEIDENTIFIER NOT NULL со значением по умолчанию NewID(). Как все же правильно сохранить данные в БД?

    26 декабря 2012 г. 6:57

Ответы

  • UpdateCommand генерируется автоматически если при генерации вы указываете ключевую колонку, так как вы попробовали сгенерировать без нее то должны сами написать запрос для обновления

    Попробуйте подписаться на событие defaulvaluesneeded и в нем для строки задайте значения по умолчанию, в часности для ключа

    private void dataGridView1_DefaultValuesNeeded(object sender, DataGridViewRowEventArgs e)
    {
        e.Row.Cells["ID"].Value = Guid.NewGuid();
        
    }


    • Предложено в качестве ответа Abolmasov Dmitry 28 декабря 2012 г. 7:27
    • Помечено в качестве ответа tzi0 28 декабря 2012 г. 19:59
    28 декабря 2012 г. 6:44
  • Вы каждый раз создаете новый dataset при этом данные о структуре таблиц у вас не известна поэтому и происходит ошибка, используйте
    SqlDataAdapter, он позволяет строить запросы, более подробно SqlCommandBuilder
    • Помечено в качестве ответа tzi0 28 декабря 2012 г. 19:59
    28 декабря 2012 г. 17:58

Все ответы

  • По всей видимости у вас создается новая запись в таблице в пустыми значениями, и при сохранении именно она выдает ошибки

    попробуйте вызвать метод GetChanges у DataSet что бы получить измененные строки и уже их сохранять

    26 декабря 2012 г. 10:55
  • Можно пример? Это мне для каждой строки UPDATE или INSERT делать нужно?
    26 декабря 2012 г. 11:42
  • нет, вам нужно вызвать метод GetChanges() для таблицы в вашем случае если правильно понимаю abiturienti, и уже его передать в метод update обьекта SQLDataAdapter
    adapter.Update(abiturienti.GetChanges())
    более подробно можно прочитать вот тут Updating Data Sources with DataAdapters (ADO.NET)
    26 декабря 2012 г. 12:05
  • Пишет, что не может сконвертировать из System.Data.DataTable в BD_KURS_VAR0.insboardDataSet.abiturientiDataTable, хотя обе сущности таблицы

    26 декабря 2012 г. 13:27
  • Покажите ваш новый код, странная ошибка

    26 декабря 2012 г. 19:10
  • private void btnSave_Click(object sender, EventArgs e)
            {
                try
                {
                    this.Validate();
                    this.abiturientiBindingSource.EndEdit();
                    this.abiturientiTableAdapter.Update(this.insboardDataSet.abiturienti.GetChanges());
                    MessageBox.Show("Update successful");
                }
                catch (System.Exception ex)
                {
                    MessageBox.Show("Update failed");
                }
            }

    27 декабря 2012 г. 8:32
  • а какой тип у
    abiturientiTableAdapter

    27 декабря 2012 г. 8:35
  • Честно говоря, я сам не понял почему такой тип. Я БД привязываю вручную через биндинг сорс, где указываю таблицу абитуриенты

    27 декабря 2012 г. 8:46
  • Посмотрите определения там будет более понятно что за тип
    27 декабря 2012 г. 8:52
  • private insboardDataSetTableAdapters.abiturientiTableAdapter abiturientiTableAdapter;

    В принципе то же самое

    В общем это класс, сгенеренный студией, когда я добавил таблицу.

     public partial class abiturientiTableAdapter : global::System.ComponentModel.Component

    А с моим вопросом я так и не разобрался

    • Изменено tzi0 27 декабря 2012 г. 10:28
    27 декабря 2012 г. 10:22
  • Привет.

    У вас значение NewID() задано в самой таблице как значение по умолчанию, как я понял и оно будет вызываться если вы не будите вообще передавать значение данной колонки.

    Вы можете перегенирировать источник данных для DataGridView и в окне мастера на шаге выбора таблицы выберите все поля, кроме idabiturienta. Тогда сохранение должно работать, но правда не будет вывода этого поля. Оно для вас важно и его нужно выводить? (тогда найдем другое решение проблемы).


    Для связи [mail]

    27 декабря 2012 г. 12:52
  • Сделал как вы описали, теперь:

    Я в ADO.NET пока нуб ) Пример сохранения брал с мсдн, там про UpdateCommand ничего не написано

    27 декабря 2012 г. 13:29
  • UpdateCommand генерируется автоматически если при генерации вы указываете ключевую колонку, так как вы попробовали сгенерировать без нее то должны сами написать запрос для обновления

    Попробуйте подписаться на событие defaulvaluesneeded и в нем для строки задайте значения по умолчанию, в часности для ключа

    private void dataGridView1_DefaultValuesNeeded(object sender, DataGridViewRowEventArgs e)
    {
        e.Row.Cells["ID"].Value = Guid.NewGuid();
        
    }


    • Предложено в качестве ответа Abolmasov Dmitry 28 декабря 2012 г. 7:27
    • Помечено в качестве ответа tzi0 28 декабря 2012 г. 19:59
    28 декабря 2012 г. 6:44
  • Я немного изменил код. У меня несколько таблиц выводятся в один датагрид:

    private void cbTables_SelectedIndexChanged(object sender, EventArgs e)
            {
                fillGrid(cbTables.SelectedItem.ToString());
            }
    
            private void fillGrid(string table)
            {
                string _table = "";
                switch (table)
                {
                    case "Абитуриенты": _table = "abiturienti"; break;
                    case "Факультеты": _table = "fakulteti"; break;
                    case "Специальности": _table = "specialnosti"; break;
                    case "Экзамены": _table = "ekzameni"; break;
                    case "Формы обучения": _table = "formiobucheniya"; break;
                }
    
                try
                {
                    con.Open();
                    da = new SqlDataAdapter("SELECT * FROM " + _table, con);
                    ds = new DataSet();
                    da.Fill(ds, "insboard");
                    bs = new BindingSource();
                    bs.DataSource = ds.Tables[0].DefaultView;
    
                    dgwTables.DataSource = bs;
                    bnavTables.BindingSource = bs;
                }
                catch (Exception ex)
                {
                    MessageBox.Show(ex.Message, "Ошибка соединения");
                }
    
            }
    
            private void btnSaveAbit_Click(object sender, EventArgs e)
            {
                try
                {
                    this.Validate();
                    this.bs.EndEdit();
                    this.da.Update(ds.Tables[0].GetChanges());
                    MessageBox.Show("Update successful");
                }
                catch (System.Exception ex)
                {
                    MessageBox.Show(ex.Message,"Update failed");
                }
            }
    private void dgwTables_DefaultValuesNeeded(object sender, DataGridViewRowEventArgs e)
            {
                e.Row.Cells[0].Value = Guid.NewGuid();
            }


    При изменении строки все та же ошибка с UpdateCommand...


    • Изменено tzi0 28 декабря 2012 г. 16:36
    • Помечено в качестве ответа tzi0 28 декабря 2012 г. 19:59
    • Снята пометка об ответе tzi0 28 декабря 2012 г. 19:59
    28 декабря 2012 г. 16:34
  • Вы каждый раз создаете новый dataset при этом данные о структуре таблиц у вас не известна поэтому и происходит ошибка, используйте
    SqlDataAdapter, он позволяет строить запросы, более подробно SqlCommandBuilder
    • Помечено в качестве ответа tzi0 28 декабря 2012 г. 19:59
    28 декабря 2012 г. 17:58
  • Всем огромное спасибо, разобрался:

    builder.GetUpdateCommand();

    помогло

    28 декабря 2012 г. 19:59