Модераторы: gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Обновление БД средствами DataAdapter, Хотябы пару примерчиков... 
V
    Опции темы
kaa
Дата 5.1.2006, 23:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 817
Регистрация: 5.11.2005

Репутация: нет
Всего: 2



Тут в процессе изучения C# столкнулся с одной проблемой - нигде немогу найти вразумительного описания обновления информации в базе данных средствами DataAdapter. Знаю что в ADO.NET логику обновления надо писать самому. А как писать, что писать, какие св-ва и методы приметь толком нигде (из того что я видел) не говориться. Я бы попросил знающих людей объяснитьsmile или направить в нужную сторонуsmile, а то уже почти неделю на месте топчусь из-за этого обновления smile
PM MAIL   Вверх
-ser-
Дата 6.1.2006, 05:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 344
Регистрация: 1.2.2005

Репутация: 4
Всего: 13



ну что ты все заладил со своей логикой обновления. видать не работал с простым АДО и уж тем более без него.
поскольку ты ничего из 700 станиц по АДО.НЕТ не понял, что не удивительно, давай начнем с конкретики, с самых азов. что ты хочешь сделать?
вообщем-то всю необходимую информацию по работе с АДО.НЕТ для себя я нашел на этом форуме.
вот, например, начни отсюда http://forum.vingrad.ru/index.php?showtopi...mp;#entry213780
но здесь нехватает одной существенной детали.
да, все знают что обновления осуществляются с помощью
Код

dataAdapter.Update( dataSet, tbl );

но в таком виде это просто не работает, то есть обновления не будут записаны, и здесь есть одна хитрость, о которой не везде упоминается (по крайней мере год назад, когда я это осваивал). а именно, для этого необходимо создать новый датасет, который и содержит только наши изменения. вот тебе метод, который и воплощает в себе твою любимую логику обновления. можешь модифицировать его под свои нужды.
Код

        public void UpdateDataSet( SqlDataAdapter da, DataSet ds, string tbl )
        {
            if ( !ds.HasChanges( DataRowState.Added | DataRowState.Modified ) )
            {
                MessageBox.Show("Hasn't been changed:" + DataRowState.Added + "  " + DataRowState.Modified);
                return;
            }

            DataSet xDataSet;            
            xDataSet = ds.GetChanges( DataRowState.Added | DataRowState.Modified );    // Changes for modified rows only.            
            if( xDataSet.HasErrors )             // Check the DataSet for errors.
                MessageBox.Show( "Has Errors" ); // Resolve errors.
            
            da.Update( xDataSet, tbl );             // After fixing errors, update the data source with da            
        }

з.ы. а вообще, чиловек, я бы даже рекомендовал попробовать использовать Enterprize Library. они там поднялись еще выше всей этой земной суеты. smile у тебя есть шанс быть в первых рядах и стать почетным консультантом по EntLib.


--------------------
"Тонкая, однако, работа." 
PM MAIL ICQ   Вверх
kaa
Дата 6.1.2006, 13:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 817
Регистрация: 5.11.2005

Репутация: нет
Всего: 2



Да, с ADO я поработать неуспел, тока с ODBC... За код конечно спасиба smile

А что такое Enterprize Library?

PM MAIL   Вверх
kaa
Дата 6.1.2006, 14:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 817
Регистрация: 5.11.2005

Репутация: нет
Всего: 2



Ладна, удачи всем пойду ломать се голову... smile smile
PM MAIL   Вверх
Exception
Дата 6.1.2006, 20:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Участник Клуба
Сообщений: 4525
Регистрация: 26.12.2004

Репутация: 2
Всего: 186



Цитата(kaa @ 6.1.2006, 14:44 Найти цитируемый пост)

А что такое Enterprize Library?

http://forum.vingrad.ru/index.php?showtopic=76374
Цитата(-ser- @ 6.1.2006, 06:26 Найти цитируемый пост)

поднялись еще выше всей этой земной суеты

Ну, ИМХО не сложно самому создать свои объекты доступа к данным. Как я всегда и делаю. А они, в свою очередь, работают на типизированном датасете.
PM   Вверх
kaa
Дата 7.1.2006, 13:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 817
Регистрация: 5.11.2005

Репутация: нет
Всего: 2



В общем на меня сегодня в три часа ночи снизошло прозрение и я родил следующий код:

Код

private void Create_Click(object sender, System.EventArgs e)
        {
            ds.Tables["trunk"].Columns["KEY"].AutoIncrement=true;
            ds.Tables["trunk"].Columns["KEY"].AutoIncrementStep=-1;
            ds.Tables["trunk"].Columns["KEY"].AutoIncrementSeed =-1;
            ds.Tables["trunk"].Columns["KEY"].Unique=true;

            DataRow row = ds.Tables["trunk"].NewRow();

            row["NUMMASCH"]="10000";
            row["NUMTRUNK"]="10000";
            row["MARK"]="10000";
            row["SER_NUM"]="10000";
            
            ds.Tables["trunk"].Rows.Add(row);
            //Ищем изменения в таблице
            DataTable dt = new DataTable("Updating");
            DataRow dr;
            dt = ds.Tables["trunk"].GetChanges();
            dr = dt.Rows[0];
            string sNUMMASCH = (string)dr[1];
            MessageBox.Show(sNUMMASCH);
            string sNUMTRUNK = (string)dr[2];
            MessageBox.Show(sNUMTRUNK);
            string sMARK = (string)dr[3];
            MessageBox.Show(sMARK);
            string sSER_NUM = (string)dr[4];
            MessageBox.Show(sSER_NUM);
string strSQL="INSERT INTO trunk(NUMMASCH,NUMTRUNK,MARK,SER_NUM) VALUES('34',"+sNUMTRUNK+","+sNUMTRUNK+","+sNUMTRUNK+");";
            OleDbCommand cs = new OleDbCommand(strSQL,cn);
            
            cs.ExecuteNonQuery();
        }


Вышеприведённый код нужен только для того, чтобы тупо вставить строку и обновить данные в БД - так сказать пробный вариант...

Но тут начинаются траблы - когда я в строковой переменной (в любой) пишу вместо цифр буквы (например
Код

row["NUMTRUNK"]="hhhhh";
) при попытке обновить БД выскакивает трабл в виде исключения неизвестного типа.


Подскажите пожалуйста, почему он так странно реагирует на буквы? Ведь переменные один хрен - строки!

Прошу не обращать внимание на корявость подставляемых значений - прога так сказать пробная...
PM MAIL   Вверх
-ser-
Дата 8.1.2006, 06:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 344
Регистрация: 1.2.2005

Репутация: 4
Всего: 13



в 3 часа ночи лучше спать
Код

string strSQL="INSERT INTO trunk(NUMMASCH,NUMTRUNK,MARK,SER_NUM) VALUES('34','"+sNUMTRUNK+"','"+sNUMTRUNK+"','"+sNUMTRUNK+"')";



--------------------
"Тонкая, однако, работа." 
PM MAIL ICQ   Вверх
kaa
Дата 8.1.2006, 13:21 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 817
Регистрация: 5.11.2005

Репутация: нет
Всего: 2



-ser-
Мдя-я-я-я... Вот это я лажанулся smile smile
Усё работат smile
PM MAIL   Вверх
kaa
Дата 15.1.2006, 00:29 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 817
Регистрация: 5.11.2005

Репутация: нет
Всего: 2



Гм, а у меня тут возник чисто академический вопрос - зачем вообще нужно средство обновления баз данных с помощью хранимых процедур, если они и запросами неплохо обновляются?

ЗЫ: Честно говоря незнаю, в тему или нет...
PM MAIL   Вверх
lovermann
Дата 15.1.2006, 00:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 285
Регистрация: 28.12.2004
Где: Прага

Репутация: нет
Всего: 8



Это уже другой вопрос (см. правила), и хотя мне бы не следовало тебе отвечать в этой теме, всё же:


Выгод много.. вот некоторые из них:
  • Писать SQL прямо в коде - это плохая манера, неудобно это. Лучше хранить запросы в процедурах. Удобно, потому что в код лезть не надо, к примеру, а только переписать процедуру в базе данных. Структура данных в DB ведь может поменяться.
  • В MS SQL Server, например, уложенные процедуры пре-компилируются и запросы оптимализируются.
  • Время работы программы уменьшается, потому что процедура исполняется на сервере и данные не нужно лишний раз гонять туда-сюда (программа - > база данных -> программа).
  • Процедура представляет собой более высокую степень абстракции. Напишешь GetListOfVIPClients("proc_CORE_GetVIPClientsNumberByIncome"); и сразу всё понятно и ясно, нежели писать запрос, который может состоять из 500 строк кода.


Это сообщение отредактировал(а) lovermann - 15.1.2006, 01:13
PM WWW ICQ   Вверх
kaa
Дата 15.1.2006, 01:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 817
Регистрация: 5.11.2005

Репутация: нет
Всего: 2



Спасибо за ответ smile
PM MAIL   Вверх
Hidrag
Дата 29.1.2006, 23:28 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 877
Регистрация: 9.4.2005
Где: JDK

Репутация: 1
Всего: 25



-ser- Спасибо за приемер в начале топика!
Немного модифицировав применил к своему случаю:

Код

        private void remBut_Click(object sender, EventArgs e)
        {
            int curr = dataGrid.CurrentRowIndex;
            string message = "Удалить текщую запись? Восстановление будет невозможным!";
            MessageBoxButtons buttons = MessageBoxButtons.YesNo;
            DialogResult result;
            result = MessageBox.Show(this, message, "", buttons, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign);
            if (result == DialogResult.Yes)
            {

                ds.Tables[0].Rows[curr].Delete();
                ds.AcceptChanges();
            }

        }

        private void okBut_Click(object sender, EventArgs e)
        {
            if (!ds.HasChanges(DataRowState.Added | DataRowState.Modified | DataRowState.Deleted))
            {
                MessageBox.Show("Hasn't been changed:" + DataRowState.Added + "  " + DataRowState.Modified);
                return;
            }

            DataSet xDataSet = new DataSet();
            xDataSet = ds.GetChanges(DataRowState.Added | DataRowState.Modified | DataRowState.Deleted);
            adapter.Update(xDataSet, "client");
        }


...то есть удаляю из таблицы строчку и хочу обновить данные, а они не хотят обнавляться, что не так?


--------------------
user posted image
PM WWW ICQ   Вверх
-ser-
Дата 30.1.2006, 09:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 344
Регистрация: 1.2.2005

Репутация: 4
Всего: 13



Hidrag
Существует масса более простейших способов удалить строку из таблицы. Например, тот же ExecuteNonQuery()
Код

SqlCommand dataCommand = new SqlCommand();
dataCommand.CommandType = CommandType.Text;
dataCommand.CommandText = "DELETE FROM tbl WHERE CustomerId = '122'";
dataCommand.Connection = conn1;

conn1.Open();
Int32 rowsAffected = dataCommand.ExecuteNonQuery();
conn1.Close(); 


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

Поскольку ты уже предупредил -Восстановление будет невозможным-, так тогда сразу и удаляй, т.е. вместо вызова ds.AcceptChanges(), вызывай метод с содержимым okBut_Click. зачем ты его вынес в отдельную кнопку? а если она не будет нажата?. А у тебя еще получается что вызов ds.AcceptChanges() сбрасывает все флаги изменений, т.е. делает DataRowState проперти равным Unchanged и соответственно ds.HasChanges всегда возвратит false.

Другой немаловажный момент я бы хотел чтобы ты обратил внимание
Код

int curr = dataGrid.CurrentRowIndex;

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

Используй CurrencyManager, для связи содержимого контрола (в нашем случае датагрид) с таблицей в датасете, в противном случае мы рискуем удалить совсем не ту строку.

Код

CurrencyManager cmngr =  CurrencyManager)this.dg1.BindingContext[dg1.DataSource, dg1.DataMember];
DataRow row = ((DataRowView) cmngr.Current).Row;


Вот теперь выбранный row совпадает с соответствующей строкой таблицы в нашем датасете.

Код

int customerID = (int)row[ "CustomerID" ];


Разумеется, после удаления строки необходимо освежить датасет и датагрид соответственно.




--------------------
"Тонкая, однако, работа." 
PM MAIL ICQ   Вверх
Hidrag
Дата 6.2.2006, 20:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 877
Регистрация: 9.4.2005
Где: JDK

Репутация: 1
Всего: 25



Исправил....

Код

        private void remBut_Click(object sender, EventArgs e)
        {
            string message = "Удалить текщую запись? Восстановление будет невозможным!";
            MessageBoxButtons buttons = MessageBoxButtons.YesNo;
            DialogResult result;
            result = MessageBox.Show(this, message, "Удаление", buttons, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1, MessageBoxOptions.RightAlign);
            if (result == DialogResult.Yes)
            {
                CurrencyManager cmngr = (CurrencyManager)this.dataGrid.BindingContext[dataGrid.DataSource, dataGrid.DataMember];
                DataRow row = ((DataRowView) cmngr.Current).Row;
                int ID = (int)row["ID"];
                cn.Open();
                string s = "DELETE FROM client WHERE ID = '" + ID.ToString() + "'";
                this.Text = s;
                OleDbCommand dC = new OleDbCommand(s,cn);
                int reader = dC.ExecuteNonQuery();
                cn.Close();
            }
        }



но где то все равно ошибка, не удаляет строку....

Ошибка: "Несоответствие типов данных в выражении условия отбора".
А это не может зависить от типа поля (ID) по которому удаляю строку в аксессе (текстовый, счетчик, числовой)?


--------------------
user posted image
PM WWW ICQ   Вверх
-ser-
Дата 7.2.2006, 05:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 344
Регистрация: 1.2.2005

Репутация: 4
Всего: 13



похоже на то, и вроде все правильно если ID имеет тип int (было бы странным если ID был текстовый).
может в аксессе свои нюансы. попробуй удалить строку с помощью этого же sql-запроса в самом аксессе, что он говорит?


--------------------
"Тонкая, однако, работа." 
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
stab
mr.DUDA
Exception

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, stab, mr.DUDA, Exception.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Базы данных под .NET | Следующая тема »


 




[ Время генерации скрипта: 0.1391 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.