问题
my question is a two part issue.
I am using the repository and unit of work pattern with entity framework. I have the following StockTransferRepository
and StockTransfer is my 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
Below is my code for 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
The code below is used within my service layer.
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
This code is working correctly but I am trying to understand if this is the best way forward for deleting child items from a parent object.
My first issue is that inside WMSBaseRepository
I have a function called GetObjectContext
which is casting my DBContext
into an ObjectContextAdapter
.
Does anyone know if there is an alternative for DBContext otherwise what is the point of DBContext if all the examples I find for deleting a child object all use ObjectContext
?
My second issue i'm trying to understand with DDD and the repository layer is that this StockTransferRepository
is solely responsible for the aggregateRoot StockTransfer
but I need to delete a StockTransferItem
from within StockTransfer. Am I doing this correctly with deleting the StockTransferItem
object using DeleteObject
within the StockTransferRepository
?
I hope someone can point me in the right direction. The code does work correctly but this post is mainly about understanding if what I am doing is the right approach or not.
I have now added the following into my service layer instead of going to the repository to remove a 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
Inside my StockTransfer model I have added the following code.
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
But I now receive an error saying the foreign key is null.
Thank you.
Mike
回答1:
If you want to remove an item you can use DbSet.Remove(object entity). The DbSets are properties on your DbContext and you can use them to delete items.
Regarding your second question, if StockTransfer
is the aggregate root, then the StockTransfer
should be responsible for handling the items it contains. You should not be allowed to delete an item without the aggregate root knowing about it (how else would the aggregate root keep the items in sync with a property like TotalStock
or something)
So instead of having a Delete
method for StockTransferItem
on your repository, you should have a DeleteTransferItem
method on your StockTransfer
and then past the StockTransfer
to an Update
function on your repository.
来源:https://stackoverflow.com/questions/9079231/repository-ef-dbcontext