2011-04-16 18 views
0

我有一個表,用戶,與相關的子表UserSecurityGroups。在我的GUI中,操作員將從列表中選擇一個用戶。該程序將檢索用戶記錄並允許操作員以一種形式編輯用戶數據。操作員還可以在另一個表單上編輯此用戶的UserSecurityGroups。LINQ to SQL持久性使用Singleton模式 - 好主意?

我正在考慮使用單例類爲用戶實例檢索和持久性返回到數據庫。如果這是一個很好的做法,我想在我的數據庫中的許多其他表中使用它。我的問題是:這是一個好習慣嗎?我缺少什麼缺陷?你會推薦什麼作爲替代方案?你的建議是否會改變,因爲我也有三到四層關係的表格(而不是上面兩個例子)?

這裏是我的推薦碼:

Imports System.Data.Linq 

Public Class UserConduit 
    Implements IDisposable 

    Private Shared _thisUserConduit As UserConduit 
    Private Shared _thisContext As VulcanDataContext 

    Protected Sub New() 
     _thisContext = New VulcanDataContext 
    End Sub 

    Public Shared Function GetInstance() 

     If _thisUserConduit Is Nothing Then 
      _thisUserConduit = New UserConduit 
     End If 

     Return _thisUserConduit 

    End Function 

    Public Function GetUserByID(ByVal thisUserName As String) As User 

     Return _thisContext.Users.SingleOrDefault(Function(u) u.Username = thisUserName) 

    End Function 

    Public Function Save() As ChangeSet 

     Dim thisSet = _thisContext.GetChangeSet 

     Try 
      _thisContext.SubmitChanges() 

     Catch ex As Exception 
      Throw 

     End Try 

     Return thisSet 

    End Function 

    Public Function Save(ByVal thisUser As User) As ChangeSet 

     If thisUser.Modified Is Nothing Then 
      _thisContext.Users.InsertOnSubmit(thisUser) 
     End If 

     Return Save() 

    End Function 


#Region " IDisposable Support " 
    Private disposedValue As Boolean = False  ' To detect redundant calls 

    ' IDisposable 
    Protected Overridable Sub Dispose(ByVal disposing As Boolean) 
     If Not Me.disposedValue Then 
      If disposing Then 
       ' free other state (managed objects). 
       _thisContext.Dispose() 
      End If 

      ' free your own state (unmanaged objects). 
      ' set large fields to null. 
     End If 
     Me.disposedValue = True 
    End Sub 


    ' This code added by Visual Basic to correctly implement the disposable pattern. 
    Public Sub Dispose() Implements IDisposable.Dispose 
     ' Do not change this code. Put cleanup code in Dispose(ByVal disposing As Boolean) above. 
     Dispose(True) 
     GC.SuppressFinalize(Me) 
    End Sub 
#End Region 

End Class 

回答

3

辛格爾頓被普遍認爲是一個反模式,這些天。這並不是說你不想保證只有一個特定類型的實例,但更好的解決方案是使用一個像StructureMap這樣的控制反轉(IoC)容器來包裝你的鍵入一個單身人士。我相信企業庫的Policy Injection塊也會這樣做。

根據我的經驗,LINQ to SQL在處理關係方面的作用是有限的...您可以輕鬆地結束每個相關表格的附加查詢。我們正在考慮轉向NHibernate,因爲額外的查詢正在成爲一個性能問題。

+1

同樣重要的是Linq to SQL datacontexts不是線程安全的,所以根據上下文的不同,單例會導致這方面的問題。 – Brook 2011-04-16 01:59:12

+0

和@Brook:謝謝。我將檢查IoC容器並使用數據上下文和線程查看問題。 – blueshift 2011-04-18 19:46:49