![]() |
|
Модераторы: gambit |
![]()
|
|
| thomas |
|
||||
![]() Доцент... почти ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1385 Регистрация: 3.10.2006 Где: " Сказочное королевство" Репутация: 35 Всего: 65 |
Приветствую всех.
Вот столкнулся с непонятной проблемой. Пишу приложение работающее с БД на MS SQL server. Для описания объектов использую статические классы, которые содержат статические методы для чтения/записи данных в БД. Поначалу каждый раз создавал новое соединение с БД. Статической использовал строку соединения.
Потом подумал что это не совсем правильно. Нужно один раз создать соединение и потом его использовать по мере необходимости (открывать/закрывать). Решил сделать не строку подключения статической, а весь объект соединения статическим. В умных книжках написано что C# гарантированно вызовет статический конструктор перед первым использование поля, свойства или метода статического класса. И потом можно постоянно его(поле например) использовать в других классах. Я попробовал создать статический объект типа SqlConnection. Сначала делал только статическое поле, а потом добавил статический конструктор и далее еще и метод.
Перед первым использованием он создается нормально. Все хорошо. Но вот когда надо второй раз использовать это соединение, оно теряет свое свойство connectionString. И вот в чем тут проблема мне никак не понять. Изменения вносимые к класс Verbinding к решению проблемы не привели. В принципе все осталось тем же самым, а запись увеличилась. Прошу подсказать или объяснить в чем я не прав. И как это исправить? Заранее спасибо. Это сообщение отредактировал(а) thomas - 17.5.2009, 15:11 -------------------- Крепко жму горло, искренне ваш Thomas. (С)vingrad Некоторые сорта флоры буквально за одно мгновение превращают нас в фауну! Проблемы негров шерифа не волнуют. |
||||
|
|||||
| Unlocker |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 125 Регистрация: 2.11.2007 Где: Москва - Знаменск (Капустин Яр) Репутация: 1 Всего: 2 |
А почему нельзя создать класс-singleton?
Смысл всего этого шаманства в том, что при первом обращении к классу объект-одиночка инициализируется, а затем к нему можно обращаться из любого места программы, не боясь ощутить потерю параметров инициализации. PS: мог где-то накосячить в синтаксисе, но без подстветки сложно набирать. Если интересно узнать про синглетон, то милости прошу открыть ставший уже классическим труд "банды четырех". Удачи --------------------
"Если бы Шекспир был программистом, то фразу "To be or not to be" он написал бы так: 2b | ! 2b." |
|||
|
||||
| thomas |
|
||||
![]() Доцент... почти ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1385 Регистрация: 3.10.2006 Где: " Сказочное королевство" Репутация: 35 Всего: 65 |
Unlocker,
Приветствую. Сделал как ты посоветовал. Через свойство.
Но результат тот же. При первом использовании соединение создается, данные из БД считываются и отображаются на экране. Но при попытке сохранить изменения после редактирования данных или новой строки вылетает ошибка об отсутствии инициализации свойства connectionString для соединения. И действительно если использовать брейкпойнты то видно в первом случае свойство присвоено как и написано в конструкторе, а во втором случае оно пустое.
Вопрос, куда девается присвоенное ранее значение и почему это происходит? Это сообщение отредактировал(а) thomas - 17.5.2009, 16:10 -------------------- Крепко жму горло, искренне ваш Thomas. (С)vingrad Некоторые сорта флоры буквально за одно мгновение превращают нас в фауну! Проблемы негров шерифа не волнуют. |
||||
|
|||||
| Idsa |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2086 Регистрация: 5.12.2006 Где: Томск Репутация: 15 Всего: 62 |
thomas, видимо, где-то этому свойству присваивается значение пустой строки (в ходе или после выполнения первого запроса). Само по себе статическое свойство изменяться не может.
|
|||
|
||||
| thomas |
|
|||
![]() Доцент... почти ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1385 Регистрация: 3.10.2006 Где: " Сказочное королевство" Репутация: 35 Всего: 65 |
Unlocker,
Даже если в классе Verbinding написать только одно статическое поле
то один раз срабатывает на УРА, а при повторном использовании вылетает исключение. Куда то девается значение свойства ConnectionString у connection. Хотя аналогичную конструкцию я использовал и в другом проекте и там все было чики чики. Добавлено через 3 минуты и 9 секунд Idsa, Привет. Да уж интересно где и почему это происходит. Ведь по идее один раз созданный статический объект меняться не должен. Сам я его ни где не меняю. Мне надо только в нужный момент подсунуть его для создания команды и открыть/закрыть при её выполнении. И откуда, блин, растут ноги? -------------------- Крепко жму горло, искренне ваш Thomas. (С)vingrad Некоторые сорта флоры буквально за одно мгновение превращают нас в фауну! Проблемы негров шерифа не волнуют. |
|||
|
||||
| Idsa |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2086 Регистрация: 5.12.2006 Где: Томск Репутация: 15 Всего: 62 |
thomas, попробуй внимательно пройтись дебаггером и все-таки определить место, где меняется значение строки соединения.
|
|||
|
||||
| thomas |
|
|||
![]() Доцент... почти ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1385 Регистрация: 3.10.2006 Где: " Сказочное королевство" Репутация: 35 Всего: 65 |
Idsa,
Не найти. При последнем закрытии перед отрисовкой формы все нормально. После добавления нового элемента и попытке его сохранить в объекте соединение свойство утеряно. -------------------- Крепко жму горло, искренне ваш Thomas. (С)vingrad Некоторые сорта флоры буквально за одно мгновение превращают нас в фауну! Проблемы негров шерифа не волнуют. |
|||
|
||||
| Idsa |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2086 Регистрация: 5.12.2006 Где: Томск Репутация: 15 Всего: 62 |
thomas, можно попробовать закачать исходники .NET и поставить breakpoint на setter свойства ConnectionString.
Это сообщение отредактировал(а) Idsa - 17.5.2009, 17:43 |
|||
|
||||
| Unlocker |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 125 Регистрация: 2.11.2007 Где: Москва - Знаменск (Капустин Яр) Репутация: 1 Всего: 2 |
Вопрос реально интересный. При работе с ADO я делал DataSet приложения синглетоном: было очень удобно.
Кстати, можно попробовать в геттере SqlConnection проставить инициализацию строкой подключения. Попробуй так:
Ну и, конечно, желательно пошагово дебаггером пройтись, чтобы посмотреть как изменяются переменные во время выполнения. --------------------
"Если бы Шекспир был программистом, то фразу "To be or not to be" он написал бы так: 2b | ! 2b." |
|||
|
||||
| thomas |
|
|||
![]() Доцент... почти ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1385 Регистрация: 3.10.2006 Где: " Сказочное королевство" Репутация: 35 Всего: 65 |
Idsa,
Unlocker, Из той же оперы вопрос. Я тут обнаружил что у меня по ходу пьесы одно соединение должно использоваться для разных команд одновременно. Объясняю на пальцах. Есть группа товаров, в ней различные категории, в категориях субкатегории , а в них уже товары. Так вот считываю данные на группу из БД, использую для этого СП и ДатаРидер. Соответственно соединение открыто. А группа то содержит категории, значиться для свойства категории объекта группа вызывается метод из класса категория для считывания данных из БД. И в этом методе должно использоваться тоже соединение, которое уже использует метод класса группа, но с другим объектом SqlCommand и StoredProcedure. Да еще оно(соединение) открыто. А тут по новой открывать. Экскпшен. Вопросец, а можно ли одно соединение использовать ОДНОВРЕМЕННО для разных объектов типа SqlCommand на основе разных StoredProcedure? -------------------- Крепко жму горло, искренне ваш Thomas. (С)vingrad Некоторые сорта флоры буквально за одно мгновение превращают нас в фауну! Проблемы негров шерифа не волнуют. |
|||
|
||||
| Unlocker |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 125 Регистрация: 2.11.2007 Где: Москва - Знаменск (Капустин Яр) Репутация: 1 Всего: 2 |
thomas, ты правда не ответил по предыдущему вопросу. Работает ли класс таким свойством?
А по второму вопросу: тут надо поэкспериментировать. Мне кажется, что один коннект можно использовать для разных команд. А вот открывать его по второму разу, как было замечено выше - вредно, т.к. исключение вылезает --------------------
"Если бы Шекспир был программистом, то фразу "To be or not to be" он написал бы так: 2b | ! 2b." |
|||
|
||||
| Idsa |
|
||||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2086 Регистрация: 5.12.2006 Где: Томск Репутация: 15 Всего: 62 |
Тут все зависит от базы. thomas, начиная с SQL Server 2005, появился режим MARS (раз, два). Инициализируется этот режим через строку соединения указанием "MultipleActiveResultSets=true;".
Да ладно. Не проверял, но мне кажется логичным, чтобы при открытом соединении вызов Open не влек за собой ровным счетом ничего. thomas, есть какие-нибудь успехи с дебагом на уровне исходников .NET? Это сообщение отредактировал(а) Idsa - 18.5.2009, 07:08 |
||||
|
|||||
| PashaPash |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1233 Регистрация: 3.1.2008 Репутация: 8 Всего: 49 |
Правильно - создавать SqlConnection, открывать и закрывать для каждой операции, а не держать один синглтон. B противном случае поимеешь вот как раз те проблемы, что в предыдущих постах описаны. Добавлено через 3 минуты и 26 секунд Создаешь SqlConnection, открываешь, выбираешь группы, закрываешь. Создаешь SqlConnection, открываешь, выбираешь категории, закрываешь. Чем плохо? |
|||
|
||||
| Idsa |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2086 Регистрация: 5.12.2006 Где: Томск Репутация: 15 Всего: 62 |
О каких проблемах ты говоришь? О том, что "обнуляется" свойство ConnectionString? Ты думаешь, эта логика прошита в каком-то из методов класса SqlConnection? |
|||
|
||||
| PashaPash |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1233 Регистрация: 3.1.2008 Репутация: 8 Всего: 49 |
Хз, где она там прошита, но я точно знаю что для SqlConnection Close and Dispose are functionally equivalent. Странно ожидать нормальной работы от диспоузнотого объекта. И, кстати, нет никакого смысла открывать надолго SqlConnection, в надежде получить бонус по скорости - это наоборот перечеркивает все фишки от pooling-a соединений. Там внутри все и так статическое. |
|||
|
||||
| Idsa |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2086 Регистрация: 5.12.2006 Где: Томск Репутация: 15 Всего: 62 |
Судя по тому коду, который предоставил thomas, connection не диспозится, а просто открывается/закрывается. Так connection подолгу и не держится. Опять же, сужу по вышеприведенному коду: там соединение открывается до выполнения операции и закрывается сразу после завершения ее выполнения. А вообще интересно, что побудило thomas отойти от традиционного подхода с созданием SqlConnection через using при каждом запросе... Я тут насчет MARS подумал... пожалуй, не будет оно так работать. С открытием подключения и выполнением запроса все будет в порядке, но как только один из потоков вызовет Connection.Close, оставшиеся задачи выполнены не будут. MARS больше подходит для ситуаций, когда нужно в одном месте выполнять несколько запросов через одно соединение. |
|||
|
||||
| PashaPash |
|
||||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1233 Регистрация: 3.1.2008 Репутация: 8 Всего: 49 |
А судя по MSDN - вызов Close эквивалентен вызову Dispose.
Жажда приключений? |
||||
|
|||||
| Idsa |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2086 Регистрация: 5.12.2006 Где: Томск Репутация: 15 Всего: 62 |
Это да... Я тут поигрался немного... ну никак мне не удается добиться того, чтобы само по себе "обнулялось" свойство ConnectionString. Вероятно, по этой же причине thomas игнорирует ORM |
|||
|
||||
| thomas |
|
||||||||||||
![]() Доцент... почти ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1385 Регистрация: 3.10.2006 Где: " Сказочное королевство" Репутация: 35 Всего: 65 |
Приветствую всех.
Была маленькая запара на сельскохозяйственной ниве, потому не мог выйти в сеть. Всем спасибо за обсуждение моей проблемы. Unlocker,
Idsa,
PashaPash,
Idsa,
Отвечаю сразу обоим. По мнению моего руководителя проекта, создание каждый раз объекта соединения с БД слишком накладная операция, а потому нужно иметь один раз созданный объект соединения и использовать его по мере необходимости. Возможно он и прав. Судите сами. Вот у меня только для того чтобы отобразить дерево Группа-Категории-Субкатегории в treeView и товары субкатегории в DataGridView нужно создать четыре соединения и сделать выборку данных. А если пользователей у программы не один, а с десяток. И далее для каждого действия с данными каждый раз создавать соединение по новой. Картина получается не вполне нормальная. Программа только и делает что создает соединения с БД. А если это все происходит не на локальном сервере в локальной сети, а через интернет? Так что PashaPash, правильно ли создавать SqlConnection и открывать/закрывать для каждой операции? Пока что я вернулся к своему первоначальному варианту, т.е. для каждой операции создание своего соединения. На следующей неделе буду общаться с преподом с глазу на глаз и спрошу про
Интересно что он скажет? Хотя с другой стороны. Вот сейчас в школе закончили семестр в котором работали небольшими группами над проектами. В нашем проекте мы с успехом смогли использовать одно соединение созданное статическим классом. Но там не было каскадных вызовов соединения. Внутри каждой операции был только вызов одной команды. Классы описывали только один объект и в них не было свойств содержащих дочерние объекты, как в моем проекте. Так что не все так однозначно. Похоже нужно глубже изучать этот вопрос и искать золотую середину. Добавлено через 2 минуты и 43 секунды Idsa,
-------------------- Крепко жму горло, искренне ваш Thomas. (С)vingrad Некоторые сорта флоры буквально за одно мгновение превращают нас в фауну! Проблемы негров шерифа не волнуют. |
||||||||||||
|
|||||||||||||
| Idsa |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2086 Регистрация: 5.12.2006 Где: Томск Репутация: 15 Всего: 62 |
Программа лишь создает экземпляры класса SqlConnection, сами физические соединения поддерживаются connection pool'ом и не разрываются при каждом вызове SqlConnection.Close.
Так ее давно уже нашли. И имя ей - Connection Pool. |
|||
|
||||
| PashaPash |
|
|||
|
Эксперт ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1233 Регистрация: 3.1.2008 Репутация: 8 Всего: 49 |
||||
|
||||
| Idsa |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2086 Регистрация: 5.12.2006 Где: Томск Репутация: 15 Всего: 62 |
Насколько я понял, ты реализуешь банальный DAL с CRUD-операциями. Все правильно? Если так, то для этих целей гораздо удобнее использовать ORM. |
|||
|
||||
| thomas |
|
|||
![]() Доцент... почти ![]() ![]() ![]() Профиль Группа: Завсегдатай Сообщений: 1385 Регистрация: 3.10.2006 Где: " Сказочное королевство" Репутация: 35 Всего: 65 |
Idsa,
ORM - wat is dat? -------------------- Крепко жму горло, искренне ваш Thomas. (С)vingrad Некоторые сорта флоры буквально за одно мгновение превращают нас в фауну! Проблемы негров шерифа не волнуют. |
|||
|
||||
| Unlocker |
|
|||
![]() Шустрый ![]() Профиль Группа: Участник Сообщений: 125 Регистрация: 2.11.2007 Где: Москва - Знаменск (Капустин Яр) Репутация: 1 Всего: 2 |
--------------------
"Если бы Шекспир был программистом, то фразу "To be or not to be" он написал бы так: 2b | ! 2b." |
|||
|
||||
| Idsa |
|
|||
|
Эксперт ![]() ![]() ![]() ![]() Профиль Группа: Участник Сообщений: 2086 Регистрация: 5.12.2006 Где: Томск Репутация: 15 Всего: 62 |
||||
|
||||
![]()
|
| Прежде чем создать тему, посмотрите сюда: | |
|
|
Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов. Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, stab, mr.DUDA, Exception. |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | Базы данных под .NET | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |