2009-02-17 107 views
0

背景:我正在將使用MS Access進行數據存儲的VB6應用程序改寫爲使用VB.NET和MS SQL Server的應用程序。在表單之間傳遞連接對象的最佳方法是什麼?

我很好奇在我的應用程序中需要連接到數據庫的不同窗體之間傳遞連接的最佳方式。現在,我已經建立了一個類來管理連接字符串傳遞以安全的方式形式之間是:

Public Class LoginCredientials 
    Private uname As String 
    Private password_hash() As Byte = {0} 
    Private server_name As String 'not used in access style databases 
    Private dbname As String 
    Private st As ServerType 'enum that would allow for different connections 
    Private tdes As TripleDES 'encryption class to encrypt password in memory 

    Public Sub New() 
     uname = "" 
     server_name = "" 
     dbname = "" 
     st = ServerType.stNotDefined 
    End Sub 
    Public Sub New(ByVal Username As String, _ 
        ByVal Password As String, _ 
        ByVal ServerName As String, _ 
        ByVal DatabaseName As String, _ 
        ByVal ServType As ServerType) 
     tdes = New TripleDES 
     uname = Username 
     password_hash = tdes.Encrypt(Password) 
     server_name = ServerName 
     dbname = DatabaseName 
     st = ServType 
     tdes = Nothing 
    End Sub 

    Public ReadOnly Property Server_Type() As ServerType 
     Get 
      Return st 
     End Get 
    End Property 
    Public ReadOnly Property CompanyName() As String 
     Get 
      Return dbname.Remove(0, 4) 
     End Get 
    End Property 
    Public Property UserName() As String 
     Get 
      Return uname 
     End Get 
     Set(ByVal value As String) 
      uname = value 
     End Set 
    End Property 
    Public Property Password() As String 
     Get 
      tdes = New TripleDES 
      Return tdes.Decrypt(password_hash) 
      tdes = Nothing 
     End Get 
     Set(ByVal value As String) 
      tdes = New TripleDES 
      password_hash = tdes.Encrypt(value) 
      tdes = Nothing 
     End Set 
    End Property 
    Public Property ServerName() As String 
     Get 
      Return server_name 
     End Get 
     Set(ByVal value As String) 
      server_name = value 
     End Set 
    End Property 
    Public Property DatabaseName() As String 
     Get 
      Return dbname 
     End Get 
     Set(ByVal value As String) 
      dbname = value 
     End Set 
    End Property 

    Public Function GetConnectionString() As String 
     Dim cstring As String = "" 
     tdes = New TripleDES 
     Select Case st 
      Case ServerType.stSQLServer 
       cstring = "User ID=" & uname & ";" & _ 
         "Password=" & tdes.Decrypt(password_hash) & ";" & _ 
         "Initial Catalog=" & dbname & ";" & _ 
         "Data Source=" & server_name 
     End Select 
     tdes = Nothing 
     Return cstring 
    End Function 
End Class

我一直在傳遞給我的對象的引用到我的任何形式的需要所涉及的連接數據庫就像這樣:

'in the form declaration 
Private myLC As LoginCredientials 
Public Sub New(ByRef lc As LoginCredientials) 
    InitializeComponent() 
    myLC = lc 
End Sub

然後,我將創建一個新的連接對象,做了什麼,我需要做的,然後關閉了連接,並摧毀了連接對象。當我很早以前在ADO中使用VB6完成此操作時,連接創建的進程在連接對象被銷燬時被終止,但似乎不再是這種情況。現在,每次創建新的連接對象並連接到我的服務器時,都會創建一個新進程,然後在關閉連接時進入睡眠狀態。一段時間後,服務器將開始拒絕連接,直到我登錄並終止我的應用創建的所有進程。很明顯,這是不正確的,我想學習正確的方法。

簡單地通過引用(或在包裝類中)傳遞相同的連接對象在我的窗體之間傳遞,讓連接對象保持打開狀態會更好嗎?

什麼是正確的方式來關閉我的連接,以便我最終不會在我的SQL服務器上得到一堆睡眠進程?是否有SQL服務器中的設置我可以調整以在一段時間不活動後自動終止進程?

你會考慮加密運行時內存密碼嗎?

謝謝你的幫助。 :)

+0

您有沒有考慮過使用Enterprise Library進行數據連接? http://www.codeplex.com/entlib – Walter 2010-01-14 15:54:07

回答

8

不應該表單之間傳遞連接對象。基本上,使用SQL Server連接時的模式是創建連接,打開連接,執行操作,然後關閉連接。

爲此,你應該有一個公共靜態方法的地方,這將產生你的SqlConnection,你會在使用語句中使用,就像這樣:

Using connection As SqlConnection = GetConnection 
    ' Use connection here. 

End Using 

這應該避免的過程,從上堆放服務器。

+0

從來沒有嘗試過這種方式,但它比我腦海中的東西更有意義。我會給這個鏡頭,謝謝! – 2009-02-17 19:46:16

+0

假設你需要調用一個sub 100次,那麼你需要在sub中打開100個連接。爲了防止您需要更高級別的上下文來進行共享。否則,這很好。 – Middletone 2009-02-17 21:27:38

+0

@Middletone:我同意,但必須採取非常嚴格的步驟才能確保正確處理連接。只是有一個連接在一起是一個非常糟糕的主意。您應該創建連接,然後將其傳遞給執行迭代的例程。 – casperOne 2009-02-17 21:59:44

1

您可以使用Using語句,它將在完成時關閉並處理連接。

Using _conn as New SqlConnection(<connstring>) 
    _conn.Open() 
    'get your data' 

End Using 

如果你沒有調用.Close(),那可能是問題所在。

1

我同意卡斯帕爾。如果您確實需要在頁面之間共享對象以減少負載,那麼您可以使用靜態成員變量來執行此操作。只要確保在執行最後一條語句時關閉連接。您還可以創建一個連接作用域,可以在最後一個事務完成時處置。如果您沒有這方面的經驗,那麼請儘早打開並關閉您的連接,並且不要通過它。

我有一個網絡應用程序,並減少一些延遲有些情況下,我使用我爲DAL創建的範圍,以便如果在子功能中有調用,他們可以使用相同的連接,而不是晉升爲MSDTC。然而,這實際上只在交易系統中是必需的。

1

作爲那就是你正在使用VB.NET,試試這個(代碼是從內存中,而不是從一個應用程序複製):

Namespace Helpers 

Public NotInheritable Class Connections 

    Private Sub New() 

    End Sub 

    Public Shared Function GetConnection(ByVal connString As String) As SqlConnection 
     Dim c as New SqlConnection(connString) 
     c.Open 
     Return c 
    End Sub 

    Public Shared Sub AdoCleanup(cn As SqlConnection, cmd As SqlCommand) 
     cmd.Dispose 
     cn.Close 
    End Sub 

End Class 

End Namespace 

,然後用它像這樣:

Private Sub LoadMyData() 

    Dim connString As String = <your conn string> 
    Dim cn As SqlConnection = Helpers.Connections.GetConnection(connString) 
    Dim cmd As New SqlCommand 

    Try 
     ' data access code 
    Catch ex As Exception 
     ' handle exception 
    Finally 
     Helpers.Connections.AdoCleanup(cn, cmd) 
    End Try 

End Sub 

您甚至可以將代碼放入GetConnection中,除非您需要靈活地使用不同的連接字符串打開多個連接。

相關問題