存储库EF DBContext

时间:2012-01-31 12:05:38

标签: asp.net-mvc entity-framework-4 repository-pattern entity-relationship ddd-repositories

我的问题是两部分问题。

我正在使用存储库和工作单元模式与实体框架。我有以下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,但我需要从内部删除StockTransferItem StockTransfer。我是否正确使用StockTransferItem中的DeleteObject删除了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

但我现在收到一条错误,说外键为空。

谢谢。

麦克

1 个答案:

答案 0 :(得分:0)

如果您要删除某个项目,可以使用DbSet.Remove(object entity)。 DbSets是DbContext上的属性,您可以使用它们删除项目。

关于第二个问题,如果StockTransfer是聚合根,那么StockTransfer应该负责处理它包含的项目。如果没有聚合根知道,你不应该被允许删除一个项目(聚合根将如何保持项目与TotalStock等属性同步)

因此,您的Delete上的StockTransferItem方法应该DeleteTransferItem,而不是StockTransfer StockTransfer方法。Update到您的存储库中的{{1}}函数。