1

我正在开发一个应用程序,其中我使用存储库(存储库模式)来处理所有 CRUD 操作(我正在使用实体框架)和用于处理上下文的工作单元。我有一个像这样的通用存储库:

Public Interface IRepository(Of TEntity As Class)

 Function GetAll() As IEnumerable(Of TEntity)
 Function GetByID(id As Object) As TEntity

End Interface


Public Class Repository(Of TEntity As Class)
  Implements IRepository(Of TEntity)

  Friend _dbContext As Entities = Nothing
  Friend _dbSet As IDbSet(Of TEntity)

  Public Sub New(ByVal context As Entities)
    If context Is Nothing Then
        Throw New ArgumentNullException("context wasn't supplied")
    End If
    Me._dbContext = context
    Me._dbSet = context.Set(Of TEntity)()
  End Sub

  Public Function GetAll() As IEnumerable(Of TEntity) Implements IRepository(Of TEntity).GetAll
    Return _dbSet.ToList().AsQueryable()
 End Function



 Public Overridable Function GetByID(id As Object) As TEntity Implements IRepository(Of     
    TEntity).GetByID
    Return _dbSet.Find(id)
 End Function


End Class


Public Interface IUnitOfWork

  ReadOnly Property PersonRepository() As IRepository(Of Person)
  ReadOnly Property OrgRepository() As IRepository(Of Organization)

  Sub Save()

End Interface


Public Class UnitOfWork
Implements IUnitOfWork
Implements IDisposable

Private _context As Entities
Private _personRepository As IRepository(Of Person)
Private _orgRepository As IRepository(Of Organization)
Private disposed As Boolean = False

Public Sub New()
    Me._context = New Entities
End Sub

Public ReadOnly Property PersonRepository() As IRepository(Of Person) Implements  IUnitOfWork.PersonRepository
    Get
        If Me._personRepository Is Nothing Then
            Me._personRepository = New Repository(Of Person)(_context)
        End If
        Return _personRepository
    End Get
End Property

.
.
.
.

Public Sub Save() Implements IUnitOfWork.Save
    _context.SaveChanges()
End Sub

Public Sub Dispose() Implements IDisposable.Dispose
    Dispose(True)
    GC.SuppressFinalize(Me)
End Sub

Protected Overridable Sub Dispose(disposing As Boolean)
    If Not Me.disposed Then
        If disposing Then
            _context.Dispose()
        End If
    End If
    Me.disposed = True
End Sub

End Class

我的问题是业务逻辑,我应该把它放在哪里?我需要计算所有返回的人,我必须计算所有这些人的总重量。这应该在人员存储库中完成还是我需要一个单独的人员类?这不是 MVC 应用程序,我的类应该由另一个应用程序使用(我没有前端类)。

我看过这个例子

在标题“更改课程控制器以使用 UnitOfWork 类和存储库”下,他这样做了

public ViewResult Details(int id) { 
  Course course = unitOfWork.CourseRepository.GetByID(id); 
  return View(course); 
 } 

怎么可能说

Course course = unitOfWork.CourseRepository.GetByID(id);

课程对象是 Course 类型,但从 unitOfWork.CourseRepository.GetByID(id) 返回的对象是课程实体类型(来自实体框架)。

我的最后一个问题……我可以在存储库类中有任何属性吗?如果我应该在存储库类中拥有计算所有人的功能和总权重功能,我还需要拥有用于存储信息的姓名、地址等属性。

我希望有人可以帮助我:)

提前致谢!

利斯

编辑:

感谢您的回答!所以你的意思是,如果我没有任何繁重的逻辑(对我来说就是这种情况),我会使用一个额外的 Person 类,其中我有我的属性,还有体重和总人数的函数,但也有函数“镜像”通用存储库类中的函数(GetAll、GetByID)。我使用来自其他类而不是存储库类的 Person 类?我仍然不明白示例 Course course = unitOfWork.CourseRepository.GetByID(id),我认为她的存储库和工作单元的使用方式与我相同。但是当我尝试这个时, unitOfWork.CourseRepository.GetByID(id) 返回一个实体类型的对象,但课程是一个“普通”对象类型(一个只有属性的普通类)。我怎么说:A 类型的对象 = B 类型的对象?

编辑2:

非常感谢您花时间回答我!!所以你说的是有时最好不要自动生成实体而是编写 POCO 类?但是,如果我想使用我的自动生成的实体,并且我有一个名为 PersonEntity 的实体,我可以在我的控制器类中像这样使用它:

 Dim personEntity As PersonEntity

 personEntity = unitOfWork.PersonEntityRepository.GetByID(id)

但是如果我这样做,我在我的控制器类中引用了一个实体,但我想要那个吗?如果我以后需要从实体框架进行更改,最好将实体与控制器分开吗?但我仍然不明白的是,我是否应该创建一个与 autogen PersonEntity 类具有相同属性的新 Person 类并像这样在我的控制器中使用它

Dim person As Person

person = unitOfWork.PersonEntityRepository.GetByID(id)

但是随后 unitOfWork.PersonEntityRepository.GetByID(id) 将返回一个 PersonEntity 类型的对象......所以这不起作用。我应该把我的总重量和总人数函数放在哪里?

如果我理解您的意思,实体对象可以用作传输对象,但最好使用 POCO/DTO 对象。但是如果我使用 Person POCO,我还能拥有 PersonEntity 对象吗?当我返回 PersonEntity 对象时,如何填充 POCO 对象?

4

1 回答 1

0

关于“我应该把业务逻辑放在哪里”:有两种方法:

  1. 复杂的业务逻辑通常进入服务层。一项服务可能依赖一个或多个存储库来对您的模型执行 CRUD 操作。因此,代表一个业务操作的单个服务操作可能依赖于多个简单操作。然后你可以在你的控制器和其他应用程序中重用这个服务层。使用基本的 POCO/DTO 在层之间传输数据。

  2. 使用包含自己的操作逻辑的领域实体。

可以在此处找到类似的讨论,因此请查看: 存储库模式和/或/vs业务逻辑层

关于你提到的那个正在使用的例子

"Course course = unitOfWork.CourseRepository.GetByID(id);"

这是很有可能的,因为我们可以以不同的方式组合存储库和 UoW 模式。请看看这个问题https://softwareengineering.stackexchange.com/questions/151374/relationship-between-repository-and-unit-of-work

以及 Wouter de Kort 的回答 Entity Framework + Repository + Unit of Work

是的,您可以使用属性而不是 get 方法。我更喜欢 get 方法,因为它可以更好地统一使用存储库。

希望它会有所帮助。如果有其他问题,请告诉我。谢谢。

编辑后的其他答案:

不客气。我已经下载了该示例的代码并再次查看以了解您的查询,但我可以看到:行的两侧:“Course course = unitOfWork.CourseRepository.GetByID(id);” 指同一类:ContosoUniversity.Models.Course。

 public ActionResult Edit(int id)
    {
        Course course = unitOfWork.CourseRepository.GetByID(id);
        PopulateDepartmentsDropDownList(course.DepartmentID);
        return View(course);
    }

CourseController 的“Details”方法后面的代码与网页中显示的代码不同:public ActionResult Details(int id)

此外,您可以将 Person 类作为 Model 类,在类内部具有与 Person 相关的业务逻辑。并且 PersonRepository 将具有 (GetAll, GetByID) 之类的方法。如果您有许多存储库,您也可以创建一个 GenericRepository,如下所示:

class GenericRepository<TEntity> where TEntity : class

我希望现在一切都好。欢迎进一步提问。

于 2013-07-08T09:34:51.790 回答