Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Базы данных под .NET > Обновление записей DataGridView


Автор: albert21 20.2.2006, 21:56
Подскажите плиз!

Код

AdapterDisk.Fill(DiskotekaDS, "Disk");
dataGridDisk.DataSource = DiskotekaDS.Tables["Disk"];

....

for (int i = 0; i <= dataGridDisk.SelectedRows.Count - 1; ++i)
{
  AdapterDisk.DeleteCommand.CommandType=System.Data.CommandType.Text;
  AdapterDisk.DeleteCommand.Connection = oleDbConnection;
  AdapterDisk.DeleteCommand.CommandText = "DELETE FROM Disk WHERE ID=" + dataGridDisk. SelectedRows[i].Cells["ID"].Value.ToString();
  AdapterDisk.DeleteCommand.ExecuteNonQuery();
}

....

AdapterDisk.Update(DiskotekaDS, "Disk");
DiskotekaDS.Tables["Disk"].RejectChanges();



Проблема: Из базы данных запись удаляется, а из Grid`а нет! smile
Как обновить ГРИД?

Автор: Exception 21.2.2006, 11:26
DataGridView.Refresh()?

Автор: albert21 21.2.2006, 11:43
Цитата

DataGridView.Refresh()


Это я пробовал! Не помогает!

Автор: arilou 23.2.2006, 13:20
albert21, Exception, и как же вы хотите, чтобы датасет синхронизировал изменения сам? Надо удалить row из датасета, и вызвать DataAdapter.Update(). Есессно, необходимо чтобы в адаптере присутствовала эта самая DeleteCommand.

Автор: mr.DUDA 23.2.2006, 16:08
Код
AdapterDisk.Update(DiskotekaDS, "Disk");
DiskotekaDS.Tables["Disk"].RejectChanges();

Последняя строка вызывает сомнения.
Надо бы её убрать, либо заменить на AcceptChanges().

Автор: albert21 23.2.2006, 22:35
Цитата

Последняя строка вызывает сомнения.
Надо бы её убрать, либо заменить на AcceptChanges().


Пробовал, ситуация без изменений!
Вообще не понимаю в чём проблема! В ASP.NET у меня возникал подобный вопрос, но его удалось решить так:
Код

            adapter_otdel.Update(ds,"Отдел");
            ds.Tables["Отдел"].RejectChanges();            
            this.DataGrid1.DataBind();


Но там использовался просто грид! В Windows приложении я не знаю как получить набор выделенных строк, как обращаться к полям выделенной строки?

Автор: mr.DUDA 23.2.2006, 22:50
В WinForms-приложении любой контрол незамедлительно реагирует на изменения в источнике данных, к которому он привязан. Единственным подводным камнем тут может быть необходимость вызвать у контрола BeginUpdate до обновления и EndUpdate после обновления источника данных...

Автор: albert21 1.3.2006, 12:23
Всё с самого начала логично! Я произвожу изменения в самой базе данных (напрямую), а не в DataSet! Поэтому AdapterDisk.Update(DiskotekaDS, "Disk"); ни чего не делает, так как DataSet и не изменился!

Я сделал так:
Код

                private System.Data.OleDb.OleDbCommandBuilder comand_builder;
                this.comand_builder = new System.Data.OleDb.OleDbCommandBuilder(AdapterDisk);
                ....
                for (int j = 0; j < dataGridDisk.SelectedRows.Count; j++)
                {
                   DiskotekaDS.Tables["Disk"].Rows[dataGridDisk.SelectedCells[j].RowIndex].Delete();
                }


Ну а потом: AdapterDisk.Update(DiskotekaDS, "Disk");
получаю ошибку "Не был задан текс команды для командного объекта"

Подскажите, как исправить?

Автор: arilou 1.3.2006, 12:29
albert21, заполнить DataAdapter.DeleteCommand.

Цитата(albert21 @ 1.3.2006, 12:23 Найти цитируемый пост)
ни чего не делает, так как DataSet и не изменился!


Ты что, не читал мой пост?

Цитата(arilou @ 23.2.2006, 13:20 Найти цитируемый пост)
Надо удалить row из датасета, и вызвать DataAdapter.Update().



Автор: albert21 1.3.2006, 21:03
arilou, извиняюсь действительно не читал, упустил из виду почему-то!
Цитата

albert21, заполнить DataAdapter.DeleteCommand.


чем его заполнить? Ведь запись удаляется в зависимости от значения первичного ключа!
DELETE FROM Disk WHERE ID=... ???

Автор: albert21 1.3.2006, 23:06
И вообще, System.Data.OleDb.OleDbCommandBuilder должен автоматически генерить SQL команды к базе данных (таблица имеет первичный ключ).

Автор: arilou 1.3.2006, 23:47
Цитата(albert21 @ 1.3.2006, 23:06 Найти цитируемый пост)
И вообще, System.Data.OleDb.OleDbCommandBuilder должен автоматически генерить SQL команды к базе данных (таблица имеет первичный ключ).

Чтобы он смог работать, вся информация о schema должна присутствовать в датасете. А он у тебя не типизированный, и скорее всего инфы в нем нет.


Автор: Hidrag 2.3.2006, 11:57
Если запись в базе точно удаляется, то можно после удаления очистить датасет, заново наполнить его ДатаАдаптером и ДатаГрид.ДатаСорс заново приравнять к нужной таблице...

Автор: arilou 2.3.2006, 13:52
Цитата(Hidrag @ 2.3.2006, 11:57 Найти цитируемый пост)
Если запись в базе точно удаляется, то можно после удаления очистить датасет, заново наполнить его ДатаАдаптером и ДатаГрид.ДатаСорс заново приравнять к нужной таблице...

А зачем? Если все правильно настроить, то будет работать как часы smile

Автор: albert21 2.3.2006, 20:12
Цитата

А зачем? Если все правильно настроить, то будет работать как часы


Полностью согласен. Но что-то настроить не получается создавал я типизированный ДатаСет и снова получил туже картину

Файл прикрепил, может кто заинтерисуется проблемой!
База данных в папке с exe-шником

Автор: albert21 3.3.2006, 00:15
Я разобрался!!! smile Дело в том, что когда вы создаёте OleDbDataAdapter при помощи ToolBox-а Studio генерирует код:
Код

        private System.Data.OleDb.OleDbCommand oleDbSelectCommand1;
        private System.Data.OleDb.OleDbCommand oleDbInsertCommand1;
        private System.Data.OleDb.OleDbCommand oleDbUpdateCommand1;
        private System.Data.OleDb.OleDbCommand oleDbDeleteCommand1;
        private System.Data.OleDb.OleDbDataAdapter oleDbDataAdapter1;
        ...
        this.oleDbSelectCommand1 = new System.Data.OleDb.OleDbCommand();
        this.oleDbInsertCommand1 = new System.Data.OleDb.OleDbCommand();
        this.oleDbUpdateCommand1 = new System.Data.OleDb.OleDbCommand();
        this.oleDbDeleteCommand1 = new System.Data.OleDb.OleDbCommand();
        ...
        this.oleDbDataAdapter1.DeleteCommand = this.oleDbDeleteCommand1;
        this.oleDbDataAdapter1.InsertCommand = this.oleDbInsertCommand1;
        this.oleDbDataAdapter1.SelectCommand = this.oleDbSelectCommand1;
        this.oleDbDataAdapter1.UpdateCommand = this.oleDbUpdateCommand1;

Так вот, для того чтобы выше описанных проблем не возникало необходимо закоментировать всё что связано с командами Insert, Update, Delete! Тогда, при наличии OleDbCommandBuilder, команды редактирования будут генериться без проблем.

Может для кого-то это и было очевидным, но не для меня! smile
Программу я писать ещё не закончил, а следовательно может возникнуть продолжение разговора!
Всем спасибо за внимание!

Автор: Butch 18.1.2007, 16:03
Всемогущий All помоги чем можешь  smile 
устал биться головой ап стену  smile 
не стал открывать новую тему т.к. данная пересекается очень близко с моей проблемой.....
Попробую подробней описать мою проблему:
Есть класс для работы с БД Access и две формы.
Первая форма содержит dataGridView (Enable Adding=false, Enable Editinig=false, Enable Deleting=falase, Enable Column Reordering=false) и кнопку для редактирования БД(открывает вторую форму с несколькими textBox-ми, кнопками `Ок` и `Отмена`).
Код из класса для работы с БД:
Код

// MyTableAdapter - OleDbDataAdapter доступный на уровне приложения
// BSMyTable - BindingSource доступный на уровне приложения
// ds - дата сет доступный на уровне приложения
// cn - коннекшион доступный на уровне класса

public void SelectTable(string SQLTable)
        {
            MyTableAdapter = new OleDbDataAdapter(SQLTable, cn);
            MyTableAdapter.Fill(ds, "MyTable");
            BSMyTable.DataSource = ds.Tables["MyTable"];
        }
public void UpdateTable(Int32 id, string val1, string val3, bool val3)
        {
            string UpDateSQL = string.Format("UPDATE Table SET val1='{0}', val2='{1}', val3={3} WHERE id={4}",
                        val1, val2, val3, id);
            MyTableAdapter = new OleDbDataAdapter(UpDateSQL, cn);
            MyTableAdapter.Fill(ds, "MyTable");
            BSMyTable.DataSource = ds.Tables["MyTable"];
            /* Пробывал и MyTableAdapter.UpdateCommand и Update - результат тот же */
        }


на Load формы с dataGridView использую следующий код:
Код

// BD - класс для работы с БД

BD.SelectTable("Select * From MyTable Order By val1");
dataGridView1.DataSource = BD.BSMyTable;


код кнопки для вызова второй формы для едита:
Код

form2 form_ed = new form2((int)dataGridView1.SelectedRows[0].Cells[0].Value);
form_ed.ShowDialog();
dataGridView1.Refresh();


код кнопки 'Ок' на второй форме:
Код

BD.UpdateMyTable(id, textBox1.Text, textBox2.Text, checkBox3.Checked);
this.Close();


Ну вот вроде бы и все, а проблема следующая:
по нажатии кнопки 'Ок' - изменяется таблица в БД, dataGridView остается не изменым
но если закрыть и открыть форму увидим измененный дата грид

Пробывал
- MyTable.AcceptChanges(); // не полетело
- dataGridView.Refresh(); // не полетело
- ds.Clear();
  повторный вызов BD.SelectTable("...."); // летит, но криво, а криво не охото  smile 


Автор: albert21 18.1.2007, 20:17
У меня вызывает сомнения вот этот код:
Цитата

            MyTableAdapter = new OleDbDataAdapter(UpDateSQL, cn);    
            MyTableAdapter.Fill(ds, "MyTable");

Хотя может это и нормально.

Эсли у тебя типизированный ДатаСет, то могу предложить вот такой вариант:
Код

        public void UpdBook(DataGridView dataGridParent, DataSetBiblion dts, object name, object izdat, int year, object udk, object bbk, int isbn, object image, /*object kategor,*/ int vsego, object annotation)
        {
            CurrencyManager cmgr = (CurrencyManager)dataGridParent.BindingContext[dataGridParent.DataSource];
            DataRow dr = ((DataRowView)cmgr.Current).Row;
            dr.BeginEdit();
            dr["Название"] = Convert.ToString(name);
            dr["Издательство"] = Convert.ToString(izdat);
            dr["Год"] = year;
            dr["УДК"] = Convert.ToString(udk);
            dr["ББК"] = Convert.ToString(bbk);
            dr["ISBN"] = isbn;
            dr["Обложка"] = Convert.ToString(image);
            //dr["Раздел"] = Convert.ToString(kategor);
            dr["Количество_всего"] = vsego;
            dr["Аннотация"] = Convert.ToString(annotation);
            dr.EndEdit();
        }

...
//затем вызываем Update для запроса в БД
bookTableAdapter.Update(dataSetBiblion.Book);



А вообще по поводу твоего кода такие соображения:
Адаптер нужен для того, чтобы работать непосредственно с БД. Для того, чтобы изменения отображались в гриде необходимо удалить запись в ДатаСете, а затем указать гриду источник dataGridBook.DataSource = dataSetBiblion.Table;

Автор: RWander 31.10.2007, 23:00
в продолжении темы..
как обновить DataGridView после занесения в базу данных новой строки.  smile 

Автор: thomas 1.11.2007, 17:55
RWander, 
Если мой DGV отображает данные из таблицы ДатаСета в которую были внесены изменения, то к двум стандартным строкам кода я добавляю еще две
Код

dgvArtLijst.DataSource = null; // обнуляем то что было
dgvArtLijst.DataSource = cyber.DS; //стандартный код что бы указать источник данных 
dgvArtLijst.DataMember = "artikelen"; // стандартный код что бы указать имя таблицы
dgvArtLijst.Refresh(); // перерисовываем DGV


Если же таблица ДатаСета, которая отображается в DGV, не содержит в себе обновленные данные, то надо по-новой выполнить запрос к БД и заполнить таблицу ДС обновленными данными и после этого вывести в DGV.

Автор: insaneghost 12.10.2009, 09:55
а еще есть какой-нибудь способ обновить dgv без изменения у него datasource?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)