0

我的问题是两部分问题。储存库EF DBContext

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

但我现在收到一个错误,说外键是空的。

谢谢。

迈克

回答

0

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

关于你的第二个问题,如果StockTransfer是聚合根,那么StockTransfer应负责处理它包含的项目。你不应该被允许,而不聚合根知道关于它(怎么回事就聚集根保持项目的同步与属性像TotalStock或东西)

上删除项目,以便而不是有Delete方法的StockTransferItem您的存储库中,您应该有DeleteTransferItem方法在您的StockTransfer上,然后通过StockTransfer到您的存储库上的Update函数。

+0

谢谢您的回复。我在尝试这个例子之前,最初尝试了一些类似的东西。我遇到的问题是它抱怨外键被设置为空。 – user1180223 2012-01-31 15:07:51

+0

是的,这可能是一个问题。这可能与一个悬而未决的StockTransferItem有关。您的存储库是特定于实现的,您可以确保EF实现删除StockTransferItem,但这不应该是您将暴露给外部世界的东西 – 2012-01-31 15:10:21

+0

我已经使用我正在使用的新代码更新了OP。您能否提供一个示例来删除StockTransferItem? – user1180223 2012-02-01 08:54:38