Репозиторий EF DBContext - PullRequest
       34

Репозиторий EF DBContext

0 голосов
/ 31 января 2012

мой вопрос состоит из двух частей.

Я использую репозиторий и единицу работы с сущностью. У меня есть 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, иначе какой смысл DBContext, если все примеры, которые я нахожу для удаления дочернего объекта, все используют ObjectContext?

Моя вторая проблема, которую я пытаюсь понять с помощью 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

Но теперь я получаю сообщение о том, что внешний ключ имеет значение null.

Спасибо.

Mike

1 Ответ

0 голосов
/ 31 января 2012

Если вы хотите удалить элемент, вы можете использовать DbSet.Remove (объектная сущность) .DbSets - это свойства вашего DbContext, и вы можете использовать их для удаления элементов.

Что касается вашего второго вопроса, если StockTransfer является совокупным корнем, то StockTransfer должен отвечать за обработку элементов, которые он содержит,Вам не должно быть разрешено удалять элемент, если агрегатный корень не знает об этом (как иначе агрегированный корень будет синхронизировать элементы с таким свойством, как TotalStock или с чем-то другим)

Таким образом, вместо *Метод 1010 * для StockTransferItem в вашем хранилище, у вас должен быть метод DeleteTransferItem в вашем StockTransfer, а затем после StockTransfer функция Update в вашем хранилище.

...