假设我有一个名为Blog的类的域模型,该类具有名为BlogEntries的属性(包含BlogEntry类型的对象)。如果我有一个包含两个表“Blog”和“BlogEntry”的数据库模型,那么我有一个博客的1000个博客条目并非不可能。如果我要在网站上显示博客,我只想一次显示20个博客条目,所以我必须使用某种分页。我显然不希望从DB中一直提取1000条记录。
我该怎么做呢? BlogEntries属性是否应该在Blog域对象中,或者可能在存储库中?我仍然希望能够添加博客条目以及创建现有分页结果。 NHibernate映射会是什么样的?
Blog / BlogEntry只是一个例子,它也可以是客户/订单示例或任何其他主/细节场景。
请赐教!
答案 0 :(得分:1)
您必须访问其自己的存储库中的blogentry才能获取分页列表。
编辑:为什么要downvote?这是错的吗?
答案 1 :(得分:1)
我会使BlogEntry成为自己的Aggregate root,拥有自己的存储库。您可以通过查询具有给定BlogID的所有BlogEntry的BlogEntry存储库来获取特定Blog的BlogEntry实例。我无法提供有关存储库的详细信息,因为有几种不同的策略来实现存储库(一个通用存储库与多个,单独的查找器方法与一个采用复杂规范对象的方法等)。存储库的finder方法应该支持分页。
public class Blog
{
public int ID {get;set;}
// other stuff
}
public class BlogEntry
{
public int ID {get;set;}
public int BlogID {get;set;}
}
public class BlogEntryRepository
{
public IEnumerable<BlogEntry> FindByBlogID(
int blogID, int pageIndex, int pageSize)
{
// implementation
}
}
或者,(也可以将BlogEntry建模为聚合根),您可以将BlogEntryID的集合添加到Blog类中。这比在Blog类中拥有BlogEntry实例更好,因为当您想要获取Blog实例时,要加载的数据要少得多。使用这些ID,您可以选择它们的一个子集并将它们传递给接受ID集合的BlogEntry存储库方法。换句话说,您的域中将有更多逻辑来支持分页,以及存储库中更通用的getter。
public class Blog
{
public int ID {get;set;}
public IEnumerable<int> BlogEntryIDs {get;set;}
// other stuff
}
public class BlogEntry
{
public int ID {get;set;}
public int BlogID {get;set;}
}
public class BlogEntryRepository
{
public IEnumerable<BlogEntry> Get(IEnumerable<int> blogEntryIDs)
{
// implementation
}
}
这种方法的用法就像
// get the second page
var entries =
blogEntryRepo.Get(blog.BlogEntryIDs).Skip(1 * PAGE_SIZE).Take(PAGE_SIZE);
在数据库中,您将返回多行,每个博客条目一行。 (我也更喜欢返回多个结果集来从一个数据库中的所有相关表中获取所有行。我还使用SQL 2005的ROW_VERSION函数来启用数据库分页。)
我通常更喜欢第二种方法,除非典型用法显示与博客相关的数量过多(例如超过几千个)BlogEntry实例。一个包含太多int的数组会让我对性能和内存保持警惕。
答案 2 :(得分:-1)
对于博客条目的收集,您可以使用BatchSize属性。它将不允许您从数据库中选择所有集合,只需要选择所需的值。