0

我的問題是兩部分問題。儲存庫EF DBContext

我正在使用存儲庫和工作單元模式與實體框架。我有以下StockTransferRepository和StockTransfer是我的aggregateRoot。

Public Class StockTransferRepository 
    Inherits WMSBaseRepository(Of StockTransfer, Int64, Dictionary(Of String, String)) 
    Implements IStockTransferRepository 

    Public Sub New(uow As IUnitOfWork) 
     MyBase.New(uow) 
    End Sub 

    Public Overrides Function GetObjectSet() As IQueryable(Of StockTransfer) 
     Return DataContextFactory.GetWMSDBContext().StockTransfer 
    End Function 

    Public Overloads Sub Add(entity As StockTransfer) Implements IStockTransferRepository.Add 
     MyBase.Add(entity) 
    End Sub 

    ' removes a stock transfer item 
    Public Sub RemoveStockTransferItem(stockTransferItem As StockTransferItem) Implements IStockTransferRepository.RemoveStockTransferItem 
     GetObjectContext().DeleteObject(stockTransferItem) 
    End Sub 

    Public Overloads Sub Remove(entity As StockTransfer) Implements IStockTransferRepository.Remove 
     MyBase.Remove(entity) 
    End Sub 

    Public Overloads Sub Save(entity As StockTransfer) Implements IStockTransferRepository.Save 
     MyBase.Save(entity) 
    End Sub 


    ' find the stock transfer by ID 
    Public Overrides Function FindBy(id As Int64) As IQueryable(Of StockTransfer) Implements IStockTransferRepository.FindBy 
     Return GetObjectSet.Where(Function(st) st.Id = id) 
    End Function 

End Class 

下面是我對WMSBaseRepository的代碼。

Public MustInherit Class WMSBaseRepository(Of T As IAggregateRoot, TEntityKey, dbErr) 
    Inherits Repository(Of T, TEntityKey) 
    Implements IUnitOfWorkRepository 

    Public Sub New(uow As IUnitOfWork) 
     MyBase.New(uow) 
    End Sub 

    Public Function GetObjectContext() As ObjectContext 
     Return DirectCast(DataContextFactory.GetWMSDBContext(), IObjectContextAdapter).ObjectContext 
    End Function 

    Public Sub PersistCreationOf(entity As IAggregateRoot) Implements IUnitOfWorkRepository.PersistCreationOf 
     DataContextFactory.GetWMSDBContext.Entry(entity).State = EntityState.Added 
    End Sub 

    Public Sub PersistDeletionOf(entity As IAggregateRoot) Implements IUnitOfWorkRepository.PersistDeletionOf 
     ' BEWARE!!!!!!!!!!!!!!!! Use with caution 
     ' this will completely delete the record from the database 
     DataContextFactory.GetWMSDBContext().Entry(entity).State = EntityState.Deleted 
    End Sub 

    Public Sub PersistUpdateOf(entity As IAggregateRoot) Implements IUnitOfWorkRepository.PersistUpdateOf 
     DataContextFactory.GetWMSDBContext().Entry(entity).State = EntityState.Modified 
    End Sub 

End Class 

下面的代碼用在我的服務層中。

Public Function StockTransferItemRemove(removeRequest As StockTransferItemRequest) As StockTransferItemResponse Implements IStockTransferService.StockTransferItemRemove 
     ' create your objects 
     Dim removeResponse = New StockTransferItemResponse 
     Dim stockTransfer As New StockTransfer 

     Try 

      ' get the aggregate root 
      stockTransfer = _stockTransferRepository.FindBy(removeRequest.StockTransferID).FirstOrDefault 

      For Each item In stockTransfer.StockTransferItems.ToList 
       If (item.Id = removeRequest.StockTransferItemView.Id) Then 
        _stockTransferRepository.RemoveStockTransferItem(item) 
       End If 
      Next 

      ' now save the stock transfer 
      _stockTransferRepository.Save(stockTransfer) 

      Dim count As Integer = _uow.WMSCommit() 

      If (count > 0) Then 
       ' the object was saved successfully 
       removeResponse.Success = True 
      Else 
       ' the object was not saved successfully 
       removeResponse.BrokenRules.Add(New BusinessRule(String.Empty, String.Empty, Tags.Messages.Commit_Failed)) 
      End If 

     Catch ex As Exception 
      ' an unexpected error occured 
      removeResponse.BrokenRules.Add(New BusinessRule(String.Empty, String.Empty, ex.Message)) 
     End Try 


     Return removeResponse 
    End Function 

此代碼工作正常,但我想知道,如果這是一個從父對象中刪除子項進展的最佳途徑。

我的第一個問題是WMSBaseRepository裏面有一個叫做GetObjectContext的函數,它將我的DBContext轉換爲ObjectContextAdapter

有沒有人知道是否有DBContext的替代方案,否則如果我找到刪除子對象的所有示例都使用ObjectContext,那麼DBContext的意義是什麼?

我的第二個問題,我試圖與DDD理解和庫層,這StockTransferRepository對於aggregateRoot StockTransfer全權負責,但我需要從內部StockTransfer刪除StockTransferItem。我是否正確地使用DeleteObject刪除StockTransferItem對象StockTransferRepository

我希望有人能指出我正確的方向。該代碼確實工作正常,但這篇文章主要是關於如何做我的做法是正確的方法。

我現在已將以下內容添加到服務層,而不是去存儲庫中刪除StockTransferItem。

  Dim product As New ProductInfo 
      product = _productRepository.FindBy(1).FirstOrDefault 
      If (product IsNot Nothing) Then 
       stockTransfer.Remove(product.StockKeys.Where(Function(x) x.Id = removeRequest.StockTransferID).FirstOrDefault) 
      End If 

在我的StockTransfer模型中我添加了下面的代碼。

Public Sub Remove(stock As StockKey) 
     If (StockTransferContainsAnItemFor(stock)) Then 
      StockTransferItems.Remove(GetItemFor(stock)) 
     End If 
    End Sub 

    Public Function StockTransferContainsAnItemFor(stock As StockKey) As Boolean 
     Return StockTransferItems.Any(Function(x) x.Contains(stock)) 
    End Function 

    Public Function GetItemFor(stock As StockKey) As StockTransferItem 
     Return StockTransferItems.Where(Function(x) x.Contains(stock)).FirstOrDefault 
    End Function 

但我現在收到一個錯誤,說外鍵是空的。

謝謝。

邁克

回答

0

如果你想刪除就可以使用DbSet.Remove(object entity)的項目。 DbSets是DbContext上的屬性,您可以使用它們刪除項目。

關於你的第二個問題,如果StockTransfer是聚合根,那麼StockTransfer應負責處理它包含的項目。你不應該被允許,而不聚合根知道關於它(怎麼回事就聚集根保持項目的同步與屬性像TotalStock或東西)

上刪除項目,以便而不是有Delete方法的StockTransferItem您的存儲庫中,您應該有DeleteTransferItem方法在您的StockTransfer上,然後通過StockTransfer到您的存儲庫上的Update函數。

+0

謝謝您的回覆。我在嘗試這個例子之前,最初嘗試了一些類似的東西。我遇到的問題是它抱怨外鍵被設置爲空。 – user1180223 2012-01-31 15:07:51

+0

是的,這可能是一個問題。這可能與一個懸而未決的StockTransferItem有關。您的存儲庫是特定於實現的,您可以確保EF實現刪除StockTransferItem,但這不應該是您將暴露給外部世界的東西 – 2012-01-31 15:10:21

+0

我已經使用我正在使用的新代碼更新了OP。您能否提供一個示例來刪除StockTransferItem? – user1180223 2012-02-01 08:54:38