Benutzer mit den meisten Antworten
Dynamischer ConnectionString

Frage
-
Ich arbeite mit Datasets in VB.NET
Dabei wird der ConenctionString in den ApplicationSettings abgelegt. Nun möchte ich den ConnectionString aber bearbeiten können...
Wie krieg ich das hin? (Die AppSettings sind Readonly)
Besten Dank!
Sign by Danasoft - Get Your Sign
Antworten
-
Hallo,
das Problem gab es ursprünglich bei den Adaptern, weil man das vergessen hat,
und das scheint sich für diesen Sonderfall erhalten zu haben.Aber man kann Abhilfe schaffen, in dem man eine Klasse von dem Adapter ableitet.
Intern werden alle Befehle über die (protected) CommandCollection verwaltet.
Und darüber weisen die (vollständigeren) TableAdapter die Verbindung zu.Das könnte in etwa so aussehen:
Public Partial Class QueriesTableAdapterEx Inherits QueriesTableAdapter Private _connection As SqlConnection ' Standardwert aus den Settings Public Sub New() Me.New(My.Settings.DefaultConnectionString) End Sub ' Mit eigenem ConnectionString Public Sub New(connectionString As String) Me.New(New SqlConnection(connectionString)) End Sub ' mit eigener Verbindung Public Sub New(connection As SqlConnection) Me.Connection = connection End Sub Protected Friend Property Connection() As SqlConnection Get Return Me._connection End Get Set Me._connection = value SetConnection() End Set End Property Private Sub SetConnection() For Each command As IDbCommand In MyBase.CommandCollection If command IsNot Nothing Then DirectCast(command, SqlCommand).Connection = Me.Connection End If Next End Sub End Class
Alternativ kann man den geänderten ConnectionString in den Settings zuweisen.
Das geht aber nur vor dem Erzeugen, da ansonsten der Wert intern verewigt wurde -
gilt auch für die TableAdapter.Gruß Elmar
- Als Antwort vorgeschlagen Peter Fleischer Donnerstag, 1. September 2011 16:59
- Als Antwort markiert theXploit Freitag, 2. September 2011 05:40
-
Man kann mit einer Vererbung auf die Command-Objekte und damit auch auf die Connection-Objekte zugreifen, da die Commands-Auflistung nur für Vererbung freigegeben ist (protected).
Imports System.Data.SqlClient Module Module1 Sub Main() Dim ta As New TAInherits ta.Connection = New SqlConnection("data source=xxx") Dim res = ta.ScalarQuery Console.WriteLine(res) Console.ReadKey() End Sub End Module Class TAInherits Inherits DataSet1TableAdapters.QueriesTableAdapter Friend WriteOnly Property Connection As SqlConnection Set(value As SqlConnection) For Each cmd In Me.CommandCollection With cmd.Connection If (.State And ConnectionState.Closed) <> ConnectionState.Closed Then .Close() End With cmd.Connection = value Next End Set End Property End Class
--
Viele Gruesse
Peter- Als Antwort vorgeschlagen Peter Fleischer Donnerstag, 1. September 2011 16:59
- Als Antwort markiert theXploit Freitag, 2. September 2011 05:40
Alle Antworten
-
Niemand wird gezwungen, dem Connection-Objekt einen ConnectionString aus den Application-Settings zuzuweisen. Das macht der Designer für TableAdapter so, weil das die optimale Arbeitsweise ist. Der ConnectionString wird beim Setup in den Programmordner gelegt. Da das Setup mit Schreibrechten für den Programmordner ausgestattet ist, kann zu diesem Zeitpunkt auch ein spezifischer ConnectionString erzeugt und abgelegt werden. Später hat üblicherweise nur noch der Administrator die Rechte, dort etwas zu ändern. Der Anwender ohne entsprechende Rechte sollte dort auch nichts ändern, da davon auszugehen ist, dass er das nicht überblickt.Wenn das Programm aber durch den Anwender erzeugte Connectionstrings nutzen soll, dann kann man diese direkt dem Connection-Objekt zuweisen und auch in den Anwendereinstellungen zwischenzeitlich ablegen.--
Viele Gruesse
Peter -
Hallo,
die Verbindungszeichenfolgen sind aus gutem Grund schreibgeschützt.
Denn sie landen im Programm-Verzeichnis und dort hat ein "normaler" Benutzer keine Änderungsrechte,
mehr siehe Verbindungszeichenfolgen und Konfigurationsdateien (ADO.NET)Dynamisch kannst Du einen Verbindungszeichenfolge über die Connection String Builder Klasse
des jeweiligen Providers erzeugen. Dabei könnte eine Applikationseinstellung als Vorlage dienen.Das Endergebnis kannst Du für spätere Nutzung als benutzerdefinierte Einstellung ablegen.
Die Einstellung gilt dann nur für den jeweiligen Benutzer.Und daraus eine Verbindung erzeugen und dem DataAdapter / TableAdapter zuweisen.
Gruß Elmar
-
Vielen Dank für die Antworten!!
Ich verwende "strongly typed Datasets", die ich per designer erstelle... Darin habe ich einen TableAdapter für skalare Funktionen. Beim ausführen einer solchen Funktion, kann ich die Connection gar nicht definieren! (Bei einem TableAdapter mit normalen GetData/Fill methoden kann ich die Connection übergeben...)
Wenn ich also StoredProcedures oder TableValuedFunctions ausführe, dann kann ich die Connection prüfen/bearbeiten bevor ich sie benutze. Dies kann ich aber eben nicht bei Skalaren Funktionen!?
Muss ich somit die "manuelle" Methode verwenden um Daten aus der Datenbank auszulesen? (Im Sinne von: Dim query As String = "Select..." )
Sign by Danasoft - Get Your Sign -
Wenn Du den Designer nutzt, dann wird auch die Erzeugung eines Connectionobjektes mit vorbereitet. Entweder, Du weist diesem Connection-Objekte einen eigenen passenden ConnectionString zu, oder, Du weist einfach ein eigenes Connection-Objekt zu.--
Viele Gruesse
Peter -
Danke für deine Hilfe!
Soweit verstehe ich das Konzept... Es bleibt nun die Frage wie ich einem Tableadapter, der nur Skalarfunktionen enthält, ein Connectionobjekt zuweisen kann...
Die Eigenschaft Connection fehlt, wenn man einen Tableadapter für Skalarfunktionen erstellt :((
Sign by Danasoft - Get Your Sign -
Ich verstehe nicht, welche Probleme Du hast. Beim Generieren des typisierten DataSets mit dem Designer wird im TableAdapter eine Connection-Eigenschaft generiert, die für einen anderen ConnectionString genutzt werden kann.Sub Main()Dim ta As New DataSet1TableAdapters.DataTable1TableAdapterta.Connection.ConnectionString = "data source=abc"Dim res = ta.ScalarQueryConsole.ReadKey()End Sub--
Viele Gruesse
Peter- Als Antwort vorgeschlagen Peter Fleischer Donnerstag, 1. September 2011 09:37
- Nicht als Antwort vorgeschlagen theXploit Freitag, 2. September 2011 05:46
-
Herzlichen Dank für die Mühe Perter!!
Edit: Achja, entschuldige die formulierung bezüglich "Skalar TableAdapter" was ich da gemeint habe ist der "QueryTableAdapter"... (Ich glaube das ist auch der Grund wieso du mein Problem nicht nachvollziehen konntest)
Es ist natürlich gut möglich, dass ich etwas nicht verstehe aber soweit ich es tue, geht das wirklich nicht:
Dazu noch die Designer-Ansicht:
Ich habe nun also die selbe Funktion (hnwfn_ben_Accountbalance) zwei mal zu meinem DataSet hinzugefügt. Einmal als normalen TableAdapter und einmal mit einem QueryTableAdapter. Und wie das erste Bild zeigt kann ich beim QueryTableAdapter keine Connection definieren.
Ich kann natürlich einfach einen normalen TableAdapter nehmen und das Problem ist gelöst, jedoch ist das m.E. nicht der saubere Weg, da ich keine DataTable benötige und somit der QueryTableAdapter völlig genügt...
Gruss
Sign by Danasoft - Get Your Sign -
Hallo,
das Problem gab es ursprünglich bei den Adaptern, weil man das vergessen hat,
und das scheint sich für diesen Sonderfall erhalten zu haben.Aber man kann Abhilfe schaffen, in dem man eine Klasse von dem Adapter ableitet.
Intern werden alle Befehle über die (protected) CommandCollection verwaltet.
Und darüber weisen die (vollständigeren) TableAdapter die Verbindung zu.Das könnte in etwa so aussehen:
Public Partial Class QueriesTableAdapterEx Inherits QueriesTableAdapter Private _connection As SqlConnection ' Standardwert aus den Settings Public Sub New() Me.New(My.Settings.DefaultConnectionString) End Sub ' Mit eigenem ConnectionString Public Sub New(connectionString As String) Me.New(New SqlConnection(connectionString)) End Sub ' mit eigener Verbindung Public Sub New(connection As SqlConnection) Me.Connection = connection End Sub Protected Friend Property Connection() As SqlConnection Get Return Me._connection End Get Set Me._connection = value SetConnection() End Set End Property Private Sub SetConnection() For Each command As IDbCommand In MyBase.CommandCollection If command IsNot Nothing Then DirectCast(command, SqlCommand).Connection = Me.Connection End If Next End Sub End Class
Alternativ kann man den geänderten ConnectionString in den Settings zuweisen.
Das geht aber nur vor dem Erzeugen, da ansonsten der Wert intern verewigt wurde -
gilt auch für die TableAdapter.Gruß Elmar
- Als Antwort vorgeschlagen Peter Fleischer Donnerstag, 1. September 2011 16:59
- Als Antwort markiert theXploit Freitag, 2. September 2011 05:40
-
Man kann mit einer Vererbung auf die Command-Objekte und damit auch auf die Connection-Objekte zugreifen, da die Commands-Auflistung nur für Vererbung freigegeben ist (protected).
Imports System.Data.SqlClient Module Module1 Sub Main() Dim ta As New TAInherits ta.Connection = New SqlConnection("data source=xxx") Dim res = ta.ScalarQuery Console.WriteLine(res) Console.ReadKey() End Sub End Module Class TAInherits Inherits DataSet1TableAdapters.QueriesTableAdapter Friend WriteOnly Property Connection As SqlConnection Set(value As SqlConnection) For Each cmd In Me.CommandCollection With cmd.Connection If (.State And ConnectionState.Closed) <> ConnectionState.Closed Then .Close() End With cmd.Connection = value Next End Set End Property End Class
--
Viele Gruesse
Peter- Als Antwort vorgeschlagen Peter Fleischer Donnerstag, 1. September 2011 16:59
- Als Antwort markiert theXploit Freitag, 2. September 2011 05:40
-
Herzlichen Dank an Peter und Elmar!!!
Das Funktioniert bestens!
Gruss
Sign by Danasoft - Get Your Sign