Приветствуем на Форум Херсона. Форум Херсонской молодежи.. На данный момент Вы находитесь на форуме как Гость и имеете очень ограниченные возможности и права. Что бы писать или отвечать в темах, загружать картинки, файлы на форуме Вам нужно зарегистрироваться, что совершенно бесплатно. Регистрация очень быстрая, не откладывайте эту процедуру! Если возникнут проблемы с регистрацией напишите нам. |
|
Программирование Все вопросы по написанию программ |
|
Опции темы |
12.05.2012, 00:02 | #1 (Ссылка на пост) | ||||||||
Щас сменю себе статус
Пол:
Благодарил(а): 6,493
Благодарили 7,331 раз в 2,872 постах
Галерея:
0
Вес репутации: 98
|
Visual Studio Express C# + MySQL
Можно ли заставить работать?
У меня все никак не получается... даже MSSQL нормально подключить в GridDataView не получается. Дает только выбор файла. Но это я обошел - заменил connectionString в пропертиз на локалхост и заработало. А MySQL вообще никак, какие только connectionStrings не пробовал. При том, что коннекторы скачал и установил. :( |
||||||||
|
12.05.2012, 13:13 | #2 (Ссылка на пост) | ||||||||
Скучающий бездельник
Пол:
Адрес: Институт времени
Благодарил(а): 15,680
Благодарили 14,464 раз в 6,143 постах
Галерея:
0
Вес репутации: 181
|
так а че грид?
ты провайдера какого используешь? какойто типа TQuery? попродуй через ADO - не знаю есть ли такое в вижуал С
__________________
Пускай не стоит свеч игра, поверь опять, что победишь. В конечном счете будет прав тот, кто зажег огонь добра. |
||||||||
|
12.05.2012, 13:47 | #3 (Ссылка на пост) | ||||||||
Уже сменил себе статус
Пол:
Благодарил(а): 3,844
Благодарили 1,942 раз в 919 постах
Галерея:
0
Вес репутации: 40
|
А для чего нужен DataGridView? Только для отображения или редактирования тоже?
Для отображения должно хватать загрузки данных в DataTable\DataSet, и подстановки его в DataSource. С этой точки зрения разница только в использовании SqlConnection\SqlCommand\SqlDataAdapter либо MySqlConnection\MySqlCommand\MySqlDataAdapter. Что тот, что тот умеет загружать данные в DataTable\DataSet, с которыми уже умеет работать DataGridView. MySqlConnection должен идти вместе с коннектором Вот пару сэмплов: http://forums.mysql.com/read.php?38,115063,115063 http://ycouriel.blogspot.com/2009/10...and-mysql.html |
||||||||
|
Сказали Спасибо пользователю PhoeniXX за этот пост: | wouldnt_even (12.05.2012) |
13.05.2012, 01:42 | #4 (Ссылка на пост) | |||||||||
Щас сменю себе статус
Пол:
Благодарил(а): 6,493
Благодарили 7,331 раз в 2,872 постах
Галерея:
0
Вес репутации: 98
|
Цитата:
|
|||||||||
|
18.05.2012, 01:08 | #5 (Ссылка на пост) | ||||||||
Щас сменю себе статус
Пол:
Благодарил(а): 6,493
Благодарили 7,331 раз в 2,872 постах
Галерея:
0
Вес репутации: 98
|
Остался один вопрос по DataGridView:
данный метод прекрасно работает, если в таблице были изменения, если изменений не было, то вылетает эксепшн. private void updateOpsTable() { DataTable changesOps = dataOps.GetChanges(); foreach (DataRow dr in changesOps.Rows) { dr[1] = selectedVoyageIndex; dr[2] = selectedVesselIndex; } daOps.Update(changesOps); dataOps.AcceptChanges(); } как проверить, что изменений не было? я могу, конечно, устанавливать кнопку сэйва в Ивенте CellValueChanged, а до того случая просто держать ее дизэйблд... но как-то это кривовато на мой взгляд... Вариант без ручного апдэйта неплохо работает, но в случае быстрого заполнения выдает периодически "Ошибка параллелизма". В джаве это решалось модификатором Synchronized, в дотнете аналога пока не нашел. пока прикрутил временное решение - сохраняет по CellValueChanged каждое второе изменение private void updateOpsTable() { if (cellChangesCount % 2 == 0) { DataTable changesOps = dataOps.GetChanges(); foreach (DataRow dr in changesOps.Rows) { dr[1] = selectedVoyageIndex; dr[2] = selectedVesselIndex; } daOps.Update(changesOps); dataOps.AcceptChanges(); opsUpdBtn.Enabled = false; } } |
||||||||
|
18.05.2012, 02:14 | #6 (Ссылка на пост) | ||||||||
Щас сменю себе статус
Пол:
Благодарил(а): 6,493
Благодарили 7,331 раз в 2,872 постах
Галерея:
0
Вес репутации: 98
|
[MethodImplAttribute(MethodImplOptions.Synchronized )]
это почти решило проблему. то есть все нормально сохраняется, но если совсем уж быстро заполнять селлы, то все равно можно наткнуться на "ошибку параллелизации". "почти" решила потому что , когда заполняешь в секунду более пяти ячеек, то таки получаешь ексепшн "нарушение параллелизма". Что удивляет в этой ситуации - во всех книгах по С# говорится, что "было слизано все лучшее с джавы", но как забыли про Synchronized мне не понятно. :( |
||||||||
|
18.05.2012, 09:01 | #7 (Ссылка на пост) | ||||||||
Уже сменил себе статус
Пол:
Благодарил(а): 3,844
Благодарили 1,942 раз в 919 постах
Галерея:
0
Вес репутации: 40
|
Сохранять данные при каждом изменении ячейки немного жестоко
А когда вызывается updateOpsTable в первом варианте? И какой exception вылетает? |
||||||||
|
Эти 2 пользователей сказали Спасибо PhoeniXX за хороший пост: | ustas (18.05.2012), wouldnt_even (18.05.2012) |
18.05.2012, 09:32 | #8 (Ссылка на пост) | ||||||||
Щас сменю себе статус
Пол:
Благодарил(а): 6,493
Благодарили 7,331 раз в 2,872 постах
Галерея:
0
Вес репутации: 98
|
|||||||||
|
18.05.2012, 09:37 | #9 (Ссылка на пост) | ||||||||
Уже сменил себе статус
Пол:
Благодарил(а): 3,844
Благодарили 1,942 раз в 919 постах
Галерея:
0
Вес репутации: 40
|
"Ссылка на объект не указывает на экземпляр объекта."
Да, это обычный NullReferenceException. Он происходит когда идет обращение к обьекту, которого не существует |
||||||||
|
18.05.2012, 20:27 | #10 (Ссылка на пост) | ||||||||
Щас сменю себе статус
Пол:
Благодарил(а): 6,493
Благодарили 7,331 раз в 2,872 постах
Галерея:
0
Вес репутации: 98
|
это понятно, потому и спросил: "как проверить, что изменений не было?". оказалось, что проверка объекта на нулл и есть подтверждение, что изменений не было.
|
||||||||
|
19.05.2012, 01:09 | #11 (Ссылка на пост) | ||||||||
Щас сменю себе статус
Пол:
Благодарил(а): 6,493
Благодарили 7,331 раз в 2,872 постах
Галерея:
0
Вес репутации: 98
|
теперь главная проблема, что невозможно программно выделить строку или ячейку в DataGridView. :(
CurrentRow - readonly, а opsDgv.CurrentCell = opsDgv[1,X]; выдает ошибку: "Текущую ячейку нельзя сделать невидимой.". Google говорит, что это баг. Проблема в том, что мне нужно выводить некоторые данные из таблицы в RichTextBox, для этого мне нужно определить индекс текущей строки. Если я вешаю эту операцию на SelectionChanged ивэнт, то попытка узнать текущую строку вызывает эксепшн. Проблема решается только ожиданием ивэнта CellClick, но мне не нравится, что данные не обновляются, если юзер меняет позицию курсора без мыши (клавиатурой) |
||||||||
|
19.05.2012, 12:18 | #12 (Ссылка на пост) | |||||||||
Уже сменил себе статус
Пол:
Благодарил(а): 3,844
Благодарили 1,942 раз в 919 постах
Галерея:
0
Вес репутации: 40
|
Цитата:
Код:
int x = 1; int y = 1; dataGridView.CurrentCell = dataGridView.Rows[x].Cells[y]; Код:
var y = dataGridView.CurrentCell.ColumnIndex; var x = dataGridView.CurrentCell.RowIndex; Код:
var rowIndex = dataGridView.CurrentRow.Index; |
|||||||||
|
Сказали Спасибо пользователю PhoeniXX за этот пост: | wouldnt_even (19.05.2012) |
19.05.2012, 13:07 | #13 (Ссылка на пост) | |||||||||
Щас сменю себе статус
Пол:
Благодарил(а): 6,493
Благодарили 7,331 раз в 2,872 постах
Галерея:
0
Вес репутации: 98
|
Цитата:
в таблице >100 столбцов, я не собираюсь их все показывать юзеру к тому же клиент хочет по некоторым столбцам данные вводились комбобоксами, а при загрузке из MySQL комбобокс нормальным способом получить никак. Поэтому я столбец скрываю и создаю новый с таким же названием, но из комбоксов. проверил, все работает, данные в скрытом столбце дублируются из комбобоксов и таблица апдейтится. я ведь точно так, как ты написал и делал. в общем try {} catch () {return;} сделал дело. эксепшн игнорируется и программа прекрасно работает. по ходу уже с редактором таблиц закончил. в понедельник установлю заказчику и операторы смогут вводить и сохранять данные . |
|||||||||
|
19.05.2012, 13:14 | #14 (Ссылка на пост) | |||||||||
Уже сменил себе статус
Пол:
Благодарил(а): 3,844
Благодарили 1,942 раз в 919 постах
Галерея:
0
Вес репутации: 40
|
Цитата:
Выделение ж должно быть визуальным, а она колонка..... Но можно ж выделить боковую колонку. У ячейки можно проверить Visible ли она, и если да, то активировать, либо активировать всю строку целиком. Не сочтите за критику, но это не всегда хороший подход. Механизм exception-ов довольно медленный в .Net-е, и если их происходит много, это очень негативно скажется на быстродействии этой функциональности. |
|||||||||
|
19.05.2012, 14:52 | #15 (Ссылка на пост) | |||||||||
Щас сменю себе статус
Пол:
Благодарил(а): 6,493
Благодарили 7,331 раз в 2,872 постах
Галерея:
0
Вес репутации: 98
|
Цитата:
if (opsDgv.CurrentRow == null) return; if (opsDgv.CurrentRow.IsNewRow) return; и нет больше эксепшенов. ночью просто голова плохо соображала, |
|||||||||
|
23.05.2012, 11:34 | #16 (Ссылка на пост) | |||||||||
Уже сменил себе статус
Пол:
Благодарил(а): 3,844
Благодарили 1,942 раз в 919 постах
Галерея:
0
Вес репутации: 40
|
Пост уже удалён, наверно потому что решён, но я бы прокомментировал его часть -
Цитата:
И второй момент - генерация запроса с использованием ToString плоха, так как вообще и этот пример в частности подвержен Sql Injection. Достаточно найти на форме текстовое поле из которого берется cv.charterers, и вписать в него типа 1;DROP SomeTable; SELECT 1 Всё зависит от фильтрации в текстовом поле, энкодирования спец символов при построении запроса, типа переменной charterers, и других вещей. Может данный код ему напрямую и не подвержен, так как не видно остальных частей, но нужно не забывать о том, что такое может быть. |
|||||||||
|
Сказали Спасибо пользователю PhoeniXX за этот пост: | wouldnt_even (23.05.2012) |
23.05.2012, 13:42 | #17 (Ссылка на пост) | ||||||||
Модератор
Пол:
Благодарил(а): 30,810
Благодарили 37,603 раз в 8,037 постах
Галерея:
0
Вес репутации: 401
|
для начала хотя бы параметризированные запросы на CRUD операции
если уж не менять структуры бд совсем
__________________
Нужно делать так, как нужно. А как не нужно, делать не нужно. |
||||||||
|
Сказали Спасибо пользователю ustas за этот пост: | wouldnt_even (23.05.2012) |
23.05.2012, 13:46 | #18 (Ссылка на пост) | ||||||||
Уже сменил себе статус
Пол:
Благодарил(а): 3,844
Благодарили 1,942 раз в 919 постах
Галерея:
0
Вес репутации: 40
|
Параметризированные запросы это хорошо, но если их сильно много, то может быть проблемно заменить их везде. Самый простой способ это экондировать стринговые значения на наличие кавычек. Хотя разница по трудозатратам не сильно большая
|
||||||||
|
Сказали Спасибо пользователю PhoeniXX за этот пост: | wouldnt_even (23.05.2012) |
23.05.2012, 14:36 | #19 (Ссылка на пост) | |||||||||
Щас сменю себе статус
Пол:
Благодарил(а): 6,493
Благодарили 7,331 раз в 2,872 постах
Галерея:
0
Вес репутации: 98
|
Цитата:
Но я все равно, сегодня утром, добавление нового рейса сделал по-другому. банально: voyagesDataTable.Rows.Add(cvDataRow); voyagesDataAdapter.Update(voyagesDataTable); предварительно сделав метод private DataRow voyageToDataRow() в классе Voyage. и наоборот, при выборе уже существующего рейса для редактирование, или формирования отчетов, добавил конструктор public Voyage (DataRow dr); так вроде бы правильнее? Последний раз редактировалось wouldnt_even, 23.05.2012 в 14:41. |
|||||||||
|
23.05.2012, 14:37 | #20 (Ссылка на пост) | |||||||||
Уже сменил себе статус
Пол:
Благодарил(а): 3,844
Благодарили 1,942 раз в 919 постах
Галерея:
0
Вес репутации: 40
|
Цитата:
Хотя Typed DataSet-ы уже немного устарели, и есть всякие другие вещи типа LinqToSql\EntityFramework\nHibernate и подобные. Хотя все они делают в принципе тоже самое |
|||||||||
|
23.05.2012, 15:53 | #21 (Ссылка на пост) | |||||||||
Щас сменю себе статус
Пол:
Благодарил(а): 6,493
Благодарили 7,331 раз в 2,872 постах
Галерея:
0
Вес репутации: 98
|
Цитата:
тем более, что я класс Voyage все равно не делаю руками, а генерирую другой программой. типа: string line; System.IO.StreamReader file; try { file = new System.IO.StreamReader("c:\\voyage_templ.txt"); StreamWriter swd = new StreamWriter("C:\\constrdr.txt"); StreamWriter swv = new StreamWriter("c:\\constrvoid.txt"); StreamWriter swc = new StreamWriter("c:\\todatarow.txt"); while ((line = file.ReadLine()) != null) { counter++; string[] buff = line.Split('\"','+',' ',','); if (buff[2].Equals("int")) { swd.WriteLine("if (row[\"{0}\"].Value == DBNull.Value)", buff[1]); swd.WriteLine("{"); swd.WriteLine(" this.{0} = 0;", buff[1]); swd.WriteLine("}"); swd.WriteLine("else"); swd.WriteLine("{"); swd.WriteLine(" this.{0} = Convert.ToInt32(row[\"{1}\"].Value;", buff[1], buff[1]); swd.WriteLine("}"); swd.WriteLine(); swv.WriteLine("this.{0}=0;", buff[1]); swc.WriteLine ("dr[\"{0}\"]=Convert.ToInt32(this.{1});", buff[1], buff[1]); } и так же для float, string, DateTime и bool. в файл voyage_templ.txt кладется текст квери, который создает таблицу. |
|||||||||
|
24.05.2012, 10:30 | #22 (Ссылка на пост) | ||||||||
Щас сменю себе статус
Пол:
Благодарил(а): 6,493
Благодарили 7,331 раз в 2,872 постах
Галерея:
0
Вес репутации: 98
|
Полезно все-таки читать гуру (Феникса и Юстаса) на форуме. Позавчера мысли об изменениях в структуре таблиц меня вгоняли в уныние. сейчас, когда сделал генератор классов из квери, переделывание таблиц обошлось в 15 минут.
|
||||||||
|
Сказали Спасибо пользователю wouldnt_even за этот пост: | PhoeniXX (24.05.2012) |
24.05.2012, 10:56 | #23 (Ссылка на пост) | ||||||||
Уже сменил себе статус
Пол:
Благодарил(а): 3,844
Благодарили 1,942 раз в 919 постах
Галерея:
0
Вес репутации: 40
|
Да, автоматизация рутинных задах даже в разработке это очень хорошая практика
К слову, еще есть такая штука как T4 Templates. Она нативно поддерживается в студии, и в ней же можно их делать. Идея схожая, в них можно писать код, который будет генерировать что-то (другой код\xml\etc) - http://msdn.microsoft.com/en-us/library/bb126445.aspx http://habrahabr.ru/post/64895/ http://andir-notes.blogspot.com/2009...al-studio.html Не уверен, что оно актуально в данном случае, но просто к слову, чтоб вы знали, что есть еще такие вещи |
||||||||
|
25.05.2012, 00:32 | #24 (Ссылка на пост) | ||||||||
Щас сменю себе статус
Пол:
Благодарил(а): 6,493
Благодарили 7,331 раз в 2,872 постах
Галерея:
0
Вес репутации: 98
|
сегодня чуть руки не опустились. вчера ведь сделал все, красиво работало - раз 20 проверил. потом начал писать логику. сегодня вечером закончил, при этом, пока тестировал, сохранял все просто в файл (serialize). когда убедился, что расчеты правильные - добавил сохранение рейса в базу... и шо вы думаете? ОШИБКИ ПАРАЛЛЕЛИЗМА! при этом, что характерно, хоть кол на голове теши этой программе, хоть комп перегружай, делает апдейты исправно несколько раз, после первой такой ошибки, с таблицей делать ничего невозможно, даже другой программой специально быстро склепаной - типа загрузка таблица в датагрид и попытка изменений. Ошибка параллелизма мертво. помогает только удаление таблицы, но потом все равно некоторое время апдейтит, а потом все по-старому.
после долгих и мучительных экспериментов наткнулся на такой спасительный пост: Some general input to the wretched ConcurrencyViolation problem: I was struggling with the same problem, and the changing Double to Decimal didn't work. But to my huge relief I found that in .NET Framework v.2 the CommandBuilder has a new property "ConflictOption". If you set this to "ConflictOption.OverwriteChanges" then the database will be updated no matter if the DataSet "thinks" the database has been updated in the meantime. не уверен, что это - правильный выход, но бурю пережить может и поможет. |
||||||||
|
25.05.2012, 08:03 | #25 (Ссылка на пост) | ||||||||
Модератор
Пол:
Благодарил(а): 30,810
Благодарили 37,603 раз в 8,037 постах
Галерея:
0
Вес репутации: 401
|
засвети эксепшн который тебе выкидывают
__________________
Нужно делать так, как нужно. А как не нужно, делать не нужно. |
||||||||
|
25.05.2012, 09:44 | #26 (Ссылка на пост) | |||||||||
Щас сменю себе статус
Пол:
Благодарил(а): 6,493
Благодарили 7,331 раз в 2,872 постах
Галерея:
0
Вес репутации: 98
|
System.Data.DBConcurrencyException: Нарушение параллелизма: UpdateCommand затронула 0 из ожидаемых 1 записей.
Почесав затылок, юзер дописал через 6 минут Цитата:
Почесав затылок, юзер дописал через 16 минут хммм, почему-то если после апдэйта вместо voyageDataTable.AcceptChanges, сделать voyageDataTable = new DataTable(); voyageDataAdapter.Fill(voyageDataTable); то параллелизма нет - отакэ. |
|||||||||
|
25.05.2012, 11:26 | #27 (Ссылка на пост) | ||||||||
Уже сменил себе статус
Пол:
Благодарил(а): 3,844
Благодарили 1,942 раз в 919 постах
Галерея:
0
Вес репутации: 40
|
Насчет ConcurrencyException-ов. Типичный случай для воспроизведения -
Есть база, и есть клиентская программа, которая её изменяет. Эту программу запускают на двух компах, и на каждом из них открывают какие-то общие данные. На первом компе пользователь сохраняет данные, и они сохраняются. При попытке сохранить на втором компе - он свалится с таким exception-ом, так как данные уже другие, чем он загрузил, и поэтому он не смог их обновить, и он валится с ConcurrencyException. DataAdapter и DataSet-ы определяют были ли изменения на уровне UPDATE запросов. К примеру есть таблица ID,ColumnA,ColumnB, и у нас есть строка где ID=5,ColumnA=DataA, ColumnB=DataB Если мы изменим данные, то DataApapter сгенерит такой запрос - Код:
UPDATE SomeTable SET ColumnA=NewDataA, ColumnB=NewDataB WHERE ID=5 AND ColumnA=DataA AND ColumnB=DataB Почесав затылок, юзер дописал через 1 минуту В этом случае просто все данные перезагрузатся из базы заново. Как вариант это хорошо конечно, но если таблица большая, там >1 000 000 записей, то при этом подходе, после изменений нескольких строк, все данные из этой таблицы будут загружатся заново, что будет медленно Последний раз редактировалось PhoeniXX, 25.05.2012 в 11:54. |
||||||||
|
25.05.2012, 12:09 | #28 (Ссылка на пост) | ||||||||
Щас сменю себе статус
Пол:
Благодарил(а): 6,493
Благодарили 7,331 раз в 2,872 постах
Галерея:
0
Вес репутации: 98
|
[quote=PhoeniXX;854921]Насчет ConcurrencyException-ов. Типичный случай для воспроизведения -
Есть база, и есть клиентская программа, которая её изменяет. Эту программу запускают на двух компах, и на каждом из них открывают какие-то общие данные. это я понимаю, это нормально, базы редактируются довольно редко, база судов - вообще трогаться почти не будет. рейсы создаются максимум 3 в месяц. и только оперативная информация - несколько строк в день. но я-то запускаю программу в одном потоке на одном компе. я подозреваю, что у меня вот этот случай: If the database record contains a floating point value (even if that floating point value is not being changed) then this exception can be generated due to a rounding error. For example the value 5.6 cannot be stored without rounding the database (or in memory either, but will be represented by the approximation 5.599999...) To complicate matters slight hardware differences between the implementation of floating point calculations on CPUs can mean that for identical data this error may be thrown on one system but not on another - which means that this error can arise in production and yet even with identical data cannot be reproduced in test - it has happened to me. для клиентской программы 5.9999999999 == 6, а для sql server'а нет. я пишу в таблицу 0,0157 дней, а назад с сервера считываю 0,015699999. я уже понемногу подумываю, чтобы хранить все числа с плавающей точкой в текстовом виде. последняя надежда - попробую округлить все переменные до 5-ти знаков после запятой. Последний раз редактировалось wouldnt_even, 25.05.2012 в 13:02. |
||||||||
|
25.05.2012, 13:51 | #29 (Ссылка на пост) | ||||||||
Щас сменю себе статус
Пол:
Благодарил(а): 6,493
Благодарили 7,331 раз в 2,872 постах
Галерея:
0
Вес репутации: 98
|
только что в другом модуле, там у меня датагрид, ввожу 12345,7777 значение ячейки устанавливается 12345,778 и все последующие попытки сделать апдейт приводят к ошибке параллелизма!
блин. я могу конечно сделать все десималы чарами, но это сильно снизит возможности программы по выборкам. :( я в печали |
||||||||
|
25.05.2012, 14:19 | #30 (Ссылка на пост) | ||||||||
Модератор
Пол:
Благодарил(а): 30,810
Благодарили 37,603 раз в 8,037 постах
Галерея:
0
Вес репутации: 401
|
запили еще раз пож-ста полностью код который добавляет/редактирует данные в какой либо таблице, где эти эксепшены вылазят
+ структуру таблицы + какой у тебя движок таблиц мускула isam или innodb?
__________________
Нужно делать так, как нужно. А как не нужно, делать не нужно. |
||||||||
|
Здесь присутствуют: 1 (пользователей - 0 , гостей - 1) | |
|
|
Похожие темы | ||||
Тема | Автор | Раздел | Ответов | Последнее сообщение |
Visual Studio 2005 | Lester | Программирование | 14 | 22.10.2009 10:24 |
visual studio 2010 | Lester | Программирование | 11 | 14.04.2009 06:47 |
Visual Studio | Аркуэн | Программирование | 20 | 09.11.2007 00:42 |
Visual Studio 2008 Beta 2 | Keller | Програмное обеспечение | 25 | 18.08.2007 13:52 |
Visual Studio 2005 Final release | dyon | Общие | 2 | 15.09.2006 20:00 |