如何使用存储库模式处理子实体的分页?
我正在学习领域驱动设计。我目前正在尝试用 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) { ... }
}
当然,这会起作用,但我会失去域模型的简单性和优雅性。
如何使用存储库模式处理子实体分页的最佳实践是什么?我不是在寻找如何使用特定的库等来处理这个问题,而是寻找一种在“模式级别”上处理它的方法。
I'm learning domain driven design. I am currently trying to write a simply application in C# designing it using DDD. This application has an aggregate root A which can contain 0..n sub entities B. This could be represented with something along the lines of:
class A {
public int Id { get; }
public IList<B> { get; }
}
with a repository:
class ARepository {
public A Get(int id) { ... }
public void SaveOrUpdate(A root) { ... }
public void Delete(A root) { ... }
}
I would however like to add paging when presenting the B sub entities for a given A instance. How would I go about doing that? The best I can come up with is changing A and ARepository to something like:
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) { ... }
}
That would work, for sure, but I would loose the simplicity and elegance of the domain model.
What is the best practice for how to handle paging of sub entities with the repository pattern? I'm not looking for how to deal with this using particular libraries, etc. but rather a way to deal with it on the "pattern level".
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
简短的回答是你不应该这样做。存储库的目的是使域对象的访问变得明确。它们不应用于出于 UI 目的对数据进行分页。这是完全不同的角色,我称之为Finder。为什么?您不想用分页等 UI 概念污染您的域(存储库属于域)。您可以在此处我的博客上找到更详细的说明。
The short answer is you should not do it like this. Repository purpose is to make accessing domain objects explicit. They should not be used to page data for UI purposes. That's completely different role which I call Finder. Why? You don't want to pollute your domain (repository belongs to domain) with UI concepts like paging. You can find a more detailed explanation here, on my blog.
如果您使用像 NHibernate 这样的 ORM,您可以通过设置集合属性 (IList) 延迟加载来实现此目的,并在对象本身而不是存储库上急切地获取所需的页面或条件。例如:
您还可以在存储库中构建这些查询并在域对象中获取结果,例如:
您还可以构建更复杂的热切查询,如下所示:
http://ayende.com/blog/4367/eagerly -有效地加载实体关联与nhibernate
If you are using an ORM like NHibernate you can achieve this by setting the collection property (IList) lazy loaded, and eagerly fetch the required page or criteria on the object itself instead of the repository. ex:
you can also build these queries in the repository and get the result in the domain object like:
you can also build more complicated eager queries as described:
http://ayende.com/blog/4367/eagerly-loading-entity-associations-efficiently-with-nhibernate