2016-10-12 64 views
1

假設我有一個存儲在數據庫中的對象(在我的示例中,類Aggregation)。如果我想要刪除它,運行.Delete()似乎是一種明顯的方式。對象刪除的設計模式?

當調用此方法時,我目前的方法是從數據庫中刪除它,然後在調用它的代碼中銷燬該對象。然而,這感覺不對 - 如果調用它的代碼並不真正銷燬對象,會發生什麼情況。然後可能會發生各種不一致。

一條路徑是在調用.Delete()時設置一個標誌,然後在運行任何其他函數或子例程之前檢查該標誌。但是有沒有更漂亮的方法?

對不起,問這個問題 - 我覺得它應該更明顯,但谷歌沒有幫助。

Imports System.Data.SqlClient 

Public Class Aggregation 

    Public ReadOnly Property ID As Integer 
    Public ReadOnly Property Name As String 

    Private Sub New(ID As Integer, name As String) 
     Me.ID = ID 
     Me.Name = name 
    End Sub 

    Public Shared Function CreateNew(Name As String) As Aggregation 
     Dim query As String = "INSERT INTO TRAF_AGGREGATION (NAME) VALUES (@NAME); SELECT SCOPE_IDENTITY();" 
     Using cmd As New SqlCommand(query) 
      cmd.Parameters.AddWithValue("@NAME", Name) 

      Dim result As DataTable = Core._dm.ExecuteQuery(cmd) 
      Return New Aggregation(result.Rows(0).Item(0), Name) 
     End Using 
    End Function 

    Public Shared Function Load(AggregationID As Integer) As Aggregation 
     Dim query As String = "SELECT * FROM AGGREGATION WHERE ID = @ID;" 
     Using cmd As New SqlCommand(query) 
      cmd.Parameters.AddWithValue("@ID", AggregationID) 
      Dim result As DataTable = Core._dm.ExecuteQuery(cmd) 
      If result.Rows.Count = 0 Then 
       Throw New ArgumentOutOfRangeException("AggregationID", AggregationID, "No aggregation with this ID") 
      Else 
       Return New Aggregation(AggregationID, result(0)("NAME")) 
      End If 
     End Using 
    End Function 

    Friend Sub Rename(newName As String) 
     ... 
    End Sub 

    .... 

    Friend Sub Delete() 
     Dim query As String = "DELETE FROM AGGREGATION WHERE ID = @ID;" 
     Using cmd As New SqlCommand(query) 
      cmd.Parameters.AddWithValue("@ID", ID) 
      Core._dm.ExecuteNonQuery(cmd) 
     End Using 
     _ID = -1 
    End Sub 
End Class 
+0

「已刪除」標誌(又名邏輯刪除)是對象/關係映射的常用方式。如果你不想自己處理這些東西,你也可以使用像Entitfy Framework這樣的O/R映射器。 –

+0

你是什麼意思:調用者可以銷燬該對象?像C++中的「刪除」關鍵字? – Kata

回答

0

亞歷克斯B.建議,最好的解決辦法是使用ORM處理所有這些複雜的你。

但是如果你不這樣做,或者你不能使用它,我認爲更好的方法可能是:

  1. 從實體類(聚合)刪除所有的CRUD方法
  2. 定義排序控制器實現到實體類的CRUD方法和返回相應的結果事件/對象
  3. 定義排序連接工廠將處理對數據庫的連接,並管理各種會議
  4. 定義一個EntityMapper,將查詢結果映射到你的實體,反之亦然
  5. 定義QueryUtils將處理所有低級別的SQL語法和標準,建設一個可重用的方式

讓我們回到你的問題,關鍵是在其中執行操作的順序:先執行查詢,對象(或驅動程序)

  1. 執行此一ction將返回
  2. 你處理結果或異常
  3. 結果或異常如果一切OK,那麼你可以更新實體狀態或從應用程序上下文刪除

希望能幫助你!