【问题标题】:How to handle paging of sub entities with the repository pattern?如何使用存储库模式处理子实体的分页?
【发布时间】:2011-08-28 18:42:05
【问题描述】:

我正在学习领域驱动设计。我目前正在尝试用 C# 编写一个简单的应用程序,使用 DDD 设计它。这个应用程序有一个聚合根 A,它可以包含 0..n 个子实体 B。这可以用以下方式表示:

class A {
    public int Id { get; }
    public IList<B> { get; }
}

有一个存储库:

class ARepository {
    public A Get(int id) { ... }
    public void SaveOrUpdate(A root) { ... }
    public void Delete(A root) { ... }
}

然而,我想在为给定的 A 实例呈现 B 子实体时添加分页。我该怎么做呢?我能想到的最好的方法是将 A 和 ARepository 更改为:

class A {
    public int Id { get; }
}

class ARepository {
    public A Get(int id) { ... }
    public void SaveOrUpdate(A root) { ... }
    public void Delete(A root) { ... }

    public IList<B> GetBForA(A root, int offset, int pageSize, out int numPages) { ... }
}

这肯定行得通,但我会失去域模型的简单性和优雅性。

如何使用存储库模式处理子实体的分页的最佳做法是什么?我不是在寻找如何使用特定库等来处理这个问题,而是在寻找一种在“模式级别”上处理它的方法。

【问题讨论】:

    标签: c# domain-driven-design repository paging aggregateroot


    【解决方案1】:

    简短的回答是你不应该这样做。存储库的目的是使访问域对象显式。不应将它们用于为 UI 目的分页数据。这是完全不同的角色,我称之为 Finder。为什么?您不想使用分页等 UI 概念污染您的域(存储库属于域)。你可以在我的博客上找到更详细的解释here

    【讨论】:

    • 阅读您的博客文章,发现者听起来是个好主意。因此,基本上,在我的问题的第二个示例中,我会将 GetBForA 方法移至 BFinder 类?我的 A 域对象会是什么样子?查找器是否属于域层,作为存储库?
    • 是的,它最终会出现在 BFinder 中。您的域对象可以保持原样。在我看来,像 BFinder 这样的东西不属于领域模型,因为它们仅用于 UI 目的。
    • @SzymonPobiega 我想阅读您提到的博客文章,但链接似乎已损坏,因为它打开了另一个网站,请在更新链接时通知我们,非常感谢。
    【解决方案2】:

    如果您使用像 NHibernate 这样的 ORM,您可以通过设置集合属性 (IList) 延迟加载来实现这一点,并在对象本身而不是存储库上急切地获取所需的页面或条件。例如:

    var a = ARepository.Get(1);
    var secondPageOfBs = a.BList.AsQueryable()
                                              .OrderBy(c => c.Name)
                                              .Skip(PageSize * 2)
                                              .Take(PageSize)
                                              .ToList();
    

    您还可以在存储库中构建这些查询并在域对象中获取结果,例如:

    var a = ARepository.GetWithPagedChildren(1, PageSize * 2, PageSize);
    

    您还可以构建更复杂的急切查询,如下所述: http://ayende.com/blog/4367/eagerly-loading-entity-associations-efficiently-with-nhibernate

    【讨论】:

    • 感谢您的回复。但是,如果您理解我的意思,我正在寻找有关如何在“模式级别”上处理此问题的答案。也许在问题中添加 C# 代码是一个错误:-)。
    猜你喜欢
    • 2011-10-26
    • 2011-07-16
    • 2011-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-02
    • 1970-01-01
    相关资源
    最近更新 更多