none
Dynamischer ConnectionString RRS feed

  • 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

    Mittwoch, 31. August 2011 07:21

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
    Donnerstag, 1. September 2011 16:42
  • 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
    Donnerstag, 1. September 2011 16:56

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
    Mittwoch, 31. August 2011 08:48
  • 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

    Mittwoch, 31. August 2011 09:21
  • 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

    Mittwoch, 31. August 2011 12:01
  • 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
    Mittwoch, 31. August 2011 14:10
  • 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

    Mittwoch, 31. August 2011 15:07
  • 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.DataTable1TableAdapter
      ta.Connection.ConnectionString = "data source=abc"
      Dim res = ta.ScalarQuery
      Console.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
    Mittwoch, 31. August 2011 17:18
  • 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

     


    Donnerstag, 1. September 2011 13:14
  • 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
    Donnerstag, 1. September 2011 16:42
  • 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
    Donnerstag, 1. September 2011 16:56
  • Herzlichen Dank an Peter und Elmar!!!

    Das Funktioniert bestens!

    Gruss


    Sign by Danasoft - Get Your Sign

    Freitag, 2. September 2011 08:06