Repository EF DBContext

牧云@^-^@ 提交于 2019-12-12 02:33:36

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!