1

我的意思是,假设我的存储库中有一个方法:

Public Function GetCustomerByState(ByVal State As String) As IQueryable(Of Customer)

如果服务能够以说这个扩展的形式获得额外的数据来表示为客户获取订单:

<Extension()> _
    Public Function Include(Of T)(ByVal Source As IQueryable(Of T), ByVal Path As String) As IQueryable(Of T)
        Dim ObjectQuery = CType(Source, ObjectQuery(Of T))
        If (ObjectQuery IsNot Nothing) Then
            Return ObjectQuery.Include(Path)
        End If
        Return Source

    End Function

此扩展最有可能与通用存储库一起使用。

或者您是否应该对每个聚合根有具体的存储库实现,以准确地返回服务所需的内容,仅此而已?

那么,您的存储库是否应该返回 IQueryable?

4

2 回答 2

2

我只会提供有限的一组方法,例如:

IQueryable<T> GetQuery();
T GetByKey(K key);

原因是存储库用于提供对聚合根的数据访问的抽象,但业务逻辑负责定义应检索哪些数据。如果您将太多逻辑传递到存储库中,您将在服务和存储库之间划分逻辑。此外,您在服务中的大多数数据检索方法都不会做任何事情——它们只会调用存储库方法。

Martin Fowler清楚地说明了这一点:

存储库在域和数据映射层之间进行调解,就像内存中的域对象集合一样。客户端对象以声明方式构造查询规范,并将它们提交给 Repository 以获得满意。

在过去的几年里,Repository 和 UnitOfWork 模式在 .NET 世界中变得非常流行。但是没有人谈论这个系列的第三种模式——规范。规范是传递给存储库的抽象查询,用于定义应返回的数据。.NET 世界没有明确使用这种模式,因为 IMO Linq-To-Entities 查询是规范。

于 2011-03-08T07:30:23.387 回答
1

我会从存储库返回服务所需的一切。这是一种很好的做法,可以防止您编写重复的查询。我用 EF Code First 在 Repository 上写了一个 SO 答案,这可能会有所帮助:Entity Framework 4 CTP 4 / CTP 5 Generic Repository Pattern and Unit Testable

请注意 - 存储库模式有许多不同的实现,我建议找到一个“感觉”正确的解决方案。在小型项目中,您可以返回 IQueryable,但如果它增长,您可能会后悔设计决定,因为很难保持 DRY。

于 2011-03-08T05:33:05.720 回答