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


Автор: Papirus 16.1.2007, 14:57
Соединение создано в дизайне. Называется незатейливо "cnn". Во всех адаптерах оно используется для подключения к БД:
Код

Me._connection.ConnectionString = Global.KTD.My.MySettings.Default.cnn

Теперь встала во весь рост задача (в начале таковой не было) предоставить юзеру возможность подключаться к разным сервакам. Для этого создана форма ввода логина... Остался пустяк... изменить программно текст строки подключения.


Автор: kobra 17.1.2007, 08:47
Код

Me._connection.Close();
Me._connection.ConnectionString = @"новая строка";
Me._connection.Open();

Автор: Papirus 17.1.2007, 10:48
То кобра!
И после этого My.Settings.cnn выдаст новую строку подключения???

Добавлено @ 10:52 
Цитата(Papirus @  16.1.2007,  14:57 Найти цитируемый пост)
Me._connection.ConnectionString = Global.KTD.My.MySettings.Default.cnn

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

Автор: kobra 18.1.2007, 16:43
с Global не работал, не знаю как параметри менять

Автор: Walker 19.2.2008, 14:07
Доброго времени суток, Уважаемые жители Винграда!

Присоединяюсь к вопросу Papirus. Предполагается на машине клиента устанавливать базу в "Мои документы" профиля пользователя. Каким же образом можно менять в случае необходимости ConnectionString, сгенерированный дизайнером?
Код

Properties.Settings.Default.ConnectionString

is readonly.
ConnectionString прописывается в ApplicationScope. Выходит, согласно msdn, без прав администратора также доступно только для чтения. Неужели MS не предоставляет возможности менять путь к базе при использовании типизированного DataSet? Или можно как-нибудь через мастер подключения указать, что строка должна генерироваться из чего-нибудь навроде
Код

Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + "Путь к базе";

 smile 
Словом, Благодарен за разъяснение этого вопроса или ссылки на таковое.

Автор: thomas 19.2.2008, 15:11
Papirus, 
Walker, 
Приветствую.
Я так понимаю строка соединения прописана в Settings.
При этом студия создает(генерирует) класс, где прописаны настройки, которые указываются на вкладке Settings вашего проекта.
В этом случае свойство connectionString действительно readOnly и изменению в runtime не подлежит.

Как я вышел из этой ситуации.
Предистория.
Первый раз в программе вынужден был использовать типизированный датасет. При его создании строка соединения зашивается в класс myDS.designer.vb.
Плюс в программе мне нужны были другие настроки для пользователя. Одна из них возможность указать путь к БД, которую будет юзать программа.
Для этого я воспользовался Settings. Адля просмотра и редактирования настроек пользователем использовал PropertyGrid.

Теперь решение проблемы.
Класс Settings.Designer.vb содержит все эти свойства. Но к счастью для нас он Partial. Потому как если в процессе программирования вы измените в ручную что-то в этом классе, а потом добавите какие-либо настройки во вкладку Settings своего проекта, то студия сгенерит этот класс по-новой. И все ваши дописки и изменения в этом классе пропадут.
Для этого используем вторую часть этого класса Settings.vb - она для нас.
Вот там я и вписал свою функцию которая переопределяет строку соединения на основании того что указал пользователь в PropertyGrid.
Вот так выглядит свойство в классе который сгенерировала студия
Код

<Global.System.ComponentModel.CategoryAttribute("Application"), _
         Global.System.Configuration.ApplicationScopedSettingAttribute(), _
         Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
         Global.System.Configuration.SpecialSettingAttribute(Global.System.Configuration.SpecialSetting.ConnectionString), _
         Global.System.Configuration.DefaultSettingValueAttribute("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=""D:\MyProjects\MAIL ID\Mailing1\Mail" & _
            "ing.mdb""")> _
        Public ReadOnly Property MailingConnectionString() As String
            Get
                Return CType(Me("MailingConnectionString"), String)
            End Get
        End Property

Как видно строка соединения прописана как атрибут и не подлежит изменению. К тому же это свойство относится к application.
Поэтому в settings я добавил свое свойство типа user для указания файла БД.
Оно тоже прописано в классе Settings.Designer.vb
Код

 <Global.System.ComponentModel.CategoryAttribute("Application"), _
         Global.System.ComponentModel.DescriptionAttribute("Naam van database bestand die zal gebruikt worden in dit programma."), _
         Global.System.Configuration.UserScopedSettingAttribute(), _
         Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
         Global.System.Configuration.DefaultSettingValueAttribute(""), _
         Global.System.ComponentModel.EditorAttribute(GetType(clsFileNameEditor), GetType(System.Drawing.Design.UITypeEditor))> _
        Public Property DataBase() As String
            Get
                Return CType(Me("DataBase"), String)
            End Get
            Set(ByVal value As String)
                Me("DataBase") = Value
            End Set
        End Property

А теперь как подставить свою БД в строку соединения.
В классе settings.vb пишем
Код

Namespace My
    
    'This class allows you to handle specific events on the settings class:
    ' The SettingChanging event is raised before a setting's value is changed.
    ' The PropertyChanged event is raised after a setting's value is changed.
    ' The SettingsLoaded event is raised after the setting values are loaded.
    ' The SettingsSaving event is raised before the setting values are saved.
    Partial Friend NotInheritable Class MySettings
        Public Function SetUserOverride() As String
            Me("MailingConnectionString") = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & Chr(34) & Me.DataBase & Chr(34)
            Return Me("MailingConnectionString").ToString()
        End Function
    End Class
End Namespace

И соответственно в классе myDS.designer.vb.(класс дизайнера датасета) указываю вызов моей функции вместо вызова свойства строки подключения.
Код

 <Global.System.Diagnostics.DebuggerNonUserCodeAttribute()>  _
        Private Sub InitConnection()
            Me._connection = New Global.System.Data.OleDb.OleDbConnection
            Me._connection.ConnectionString = Global.MassPost.My.MySettings.Default.SetUserOverride()
        End Sub

Все проблема решена. Теперь пользователь при старте программы идет в форму редактирования настроек программы(форма содержит PropertyGrid) и там выставляет свои настройки.
Указывает место положения своей БД и типизированный датасет ищет БД там где он указал.
Эти настройки сохраняются в файле user .config. Если программу открыл другой пользователь, то его настройки сохраняться в его файл в его профиле.

Надеюсь это вам поможет.  smile 

Автор: Walker 19.2.2008, 16:33
Цитата(thomas @  19.2.2008,  16:11 Найти цитируемый пост)
Надеюсь это вам поможет. 

Несомненно! smile 

thomas, Благодарю за подробнейший ответ и интересное самостоятельное решение! Попробую поставить два плюса. Поздравляю с рубежом 1000!

P.S. Прошу модераторов или топикстартера спустя год пометить тему решённой.

Автор: Papirus 20.2.2008, 11:04
To Walker
Есть просьбочка. Попробовать это решение. Потом грохнуть 1-ю БД и снова попробовать... Что будет если первоначальный путь выдаст ошибку?

Автор: farad 20.2.2008, 11:51
thomas, может быть лучше предоставить создание строки подключения тому, кто это должен далать? например http://forum.vingrad.ru/forum/topic-188887.html? smile 

Автор: Jugius 14.9.2009, 19:32
гм, не знаю, активна ли еще тема за давностью лет, но.. застрял на том же вопросе :(

thomas, решение интересное, изложено все очень подробно и доступно.
но вот в этом месте:
Цитата(thomas @  19.2.2008,  15:11 Найти цитируемый пост)
И соответственно в классе myDS.designer.vb.(класс дизайнера датасета) указываю вызов моей функции вместо вызова свойства строки подключения.

есть неувязочка, при любом изменении датасета myDS дизайнер опать перепишет все по новой и строка:
Цитата(thomas @  19.2.2008,  15:11 Найти цитируемый пост)
Me._connection.ConnectionString = Global.MassPost.My.MySettings.Default.SetUserOverride()

вернется в исходную.
Еще одно замечание: 
InitConnection объявляется для каждой таблицы, одной заменой не отделаешься, проще уж сделать замену в Public ReadOnly Property MailingConnectionString.
Сейчас сам бьюсь над этой проблемой, адекватного решения пока не нашел.

подход 1: переписывать designer.vb файла settings (но при изменении он переписвывается обратно)
подход 2: попытаться перезаписать значение  Public ReadOnly Property DATAConnectionString() As String
для этого в settings.vb создал еще один Public Property, который должен подставлять.. но он не подставляет, потому как ReadOnly

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

Автор: thomas 15.9.2009, 13:35
Jugius, 
Привет.
Я остановился на 
Цитата

подход 1: переписывать designer.vb файла settings (но при изменении он переписвывается обратно)

Перезапись да происходит, если в дизайнермоде что-то переделать в ДатаСет.
Но что мешает вам во-первых сначала всехорошо продумать что будет и как в ДатаСет и только потом когда ДатаСет создан окончательно в дизайнере внести изменения в код.
А во-вторых, даже если и что-то поменяли в дизайнере во время разработки программы, то можно еще раз внести изменения в код ДатаСета.
Успехов.

ЗЫ я лично внес изменеия в код только один раз.

Автор: Pessimister 15.6.2012, 04:03
Я использовал следующий подход. Строка соединения подставляется в MySettings сразу после считывания настроек из конфигурационного файла (в моем случае она берется из реестра, куда кладется программой установки). Для этого я внес следующие изменения в Settings.vb:
Код

Namespace My
    
    'Этот класс позволяет обрабатывать определенные события в классе параметров:
    ' Событие SettingChanging возникает перед изменением значения параметра.
    ' Событие PropertyChanged возникает после изменения значения параметра.
    ' Событие SettingsLoaded возникает после загрузки значений параметров.
    ' Событие SettingsSaving возникает перед сохранением значений параметров.
    Partial Friend NotInheritable Class MySettings

        Private Sub MySettings_SettingsLoaded(sender As Object, e As System.Configuration.SettingsLoadedEventArgs) Handles Me.SettingsLoaded
            Dim keyValue As Object
            keyValue = My.Computer.Registry.GetValue("HKEY_CURRENT_USER\Software\MyCompany\MyApplication", "ConnectionString", Nothing)
            If Not keyValue Is Nothing Then Me("ConnectionString") = keyValue.ToString
        End Sub
    End Class
End Namespace



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

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