存储库 EF DBContext

发布于 2025-01-01 00:11:58 字数 5875 浏览 3 评论 0原文

我的问题是由两部分组成的问题。

我正在将存储库和工作单元模式与实体框架一起使用。我有以下 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。我在 StockTransferRepository 中使用 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

但我现在收到一条错误消息,指出外键为空。

谢谢。

麦克风

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

吃→可爱长大的 2025-01-08 00:11:58

如果要删除项目,可以使用 DbSet.Remove(对象实体). DbSet 是 DbContext 上的属性,您可以使用它们来删除项目。

关于你的第二个问题,如果 StockTransfer 是聚合根,那么 StockTransfer 应该负责处理它包含的项目。不应该允许您在聚合根不知道的情况下删除项目(否则聚合根如何使项目与 TotalStock 等属性保持同步)

所以不要使用 Delete 方法,您的存储库上的 StockTransferItem ,您的 StockTransfer 上应该有一个 DeleteTransferItem 方法,然后通过StockTransfer 到存储库上的 Update 函数。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文