私の質問は2つの部分の問題です。リポジトリ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
オブジェクトを削除すると正しく処理されますか?
誰かが正しい方向に向けることを願っています。コードは正しく機能しますが、私がやっていることが正しいアプローチかどうかを理解することが中心です。
私は今、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
ただし、外部キーがnullであるというエラーが表示されるようになりました。
ありがとうございます。マイク
ありがとうございます。私はこのサンプルが動作する前に、もともとそれに似たものを試しました。私が持っていた問題は、外部キーがnullに設定されていると不平を言うことでした。 – user1180223
ええ、それは問題になる可能性があります。おそらくぶらぶらしているStockTransferItemと関係があります。あなたのリポジトリは実装固有ですが、EF実装がStockTransferItemを削除することを確認できますが、これは外部に公開するものであってはなりません –
OPを使用している新しいコードで更新しました。 StockTransferItemを削除するための例を提供できますか? – user1180223