在NHibernate中分页 [英] Paging in NHibernate

查看:136
本文介绍了在NHibernate中分页的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

让我们说一个域模型具有一个名为Blog的类,该类具有一个称为BlogEntries的属性(其中包含BlogEntry类型的对象).如果我有一个带有两个表"Blog"和"BlogEntry"的数据库模型,那么我就有1000个博客条目是不可能的.如果要在网站上显示博客,则一次只想显示20个博客条目,因此我必须使用某种分页.我显然不希望一直从数据库中提取1000条记录.

Lets say I have a domain model with a class called Blog that has a property called BlogEntries (that contains objects of type BlogEntry). If I have a database model with two tables "Blog" and "BlogEntry", it's not impossible that I have 1000 blog entries for a blog. If I were to show the blog on a web site, I would only want to display maybe 20 blog entries at a time, so I would have to use some sort of paging. I obviously don't want 1000 records to be fetched from the DB all the time.

我将如何去做? BlogEntries属性应该在Blog域对象中还是在存储库中?我仍然希望能够添加博客条目以及获取现有条目的分页结果. NHibernate映射是什么样的?

How would I go about doing that? Should the BlogEntries property even be in the Blog domain object, or perhaps in the respository? I would still like to have the possibility to add blog entries as well as geting a paged result of existing ones. What would the NHibernate mapping look like?

Blog/BlogEntry只是一个例子,也可能是Customer/Order例子或任何其他主/详细信息场景.

The Blog/BlogEntry thing is just an example, it could just as well have been a Customer/Order example or any other master/detail scenario.

请赐教!

推荐答案

我将BlogEntry设为自己的聚合根以及自己的存储库.通过查询BlogEntry存储库中具有给定BlogID的所有BlogEntry,可以获取特定Blog的BlogEntry实例.我无法提供有关存储库的详细信息,因为有几种不同的实现存储库的策略(一个通用存储库与许多,单独的查找器方法以及采用复杂规范对象的方法等).存储库的finder方法应支持分页.

I would make BlogEntry it's own Aggregate root, with it's own repository. You would get BlogEntry instances for a particular Blog by querying the BlogEntry repository for all BlogEntry's that have a given BlogID. I can't provide specifics about the repository beyond that since there are several different strategies for implementing repositories (one generic repository vs many, separate finder methods vs one that takes a complex specification object, etc). The finder method of the repository should support paging.

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建模为聚合根),您可以向Blog类添加BlogEntryID的集合.这比将BlogEntry实例本身包含在Blog类中更好,因为当您要获取Blog实例时,要加载的数据要少得多.使用这些ID,您可以选择它们的一个子集,并将它们传递到接受ID集合的BlogEntry存储库方法中.换句话说,您的域中将有更多的逻辑来支持分页,而存储库中的逻辑将更加通用.

Alternatively, (also with BlogEntry modeled as an Aggregate root) you could add a collection of BlogEntryIDs to your Blog class. This would be better than having the BlogEntry instances themselves in the Blog class as you would have much less data to load when you want to get a Blog instance. With those IDs, you could select a subset of them and pass them into a BlogEntry repository method that accepts a collection of IDs. In other words there would be a little more logic in your domain to support the paging, and a more generic getter in the repository.

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函数来启用数据库分页.)

In the database, you would return multiple rows, one for each blog entry. (I also prefer to return multiple result sets to get all rows from all related tables in one database round trip. I also make use of SQL 2005's ROW_VERSION function to enable database paging.)

我通常更喜欢第二种方法,除非通常的用法显示与Blog相关联的BlogEntry实例数量过高(例如,超过几千).过多的int数组会使我对性能和内存保持警惕.

I generally prefer the second method, unless the typical usage shows prohibitive quantities of (e.g. more than a couple thousand) BlogEntry instances associated with a Blog. An array of too many int's would make me wary of performance and memory.

这篇关于在NHibernate中分页的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆