c# – 如何使用NHibernate和Repository Pattern从域对象的属性返回分页列表

从文本“The Repository”模式是Domain和Data Mapper层之间的Mediator.凉.因此,例如,可能存在Repository接口和Base Domain Object

public interface Repository<DomainT> where DomainT : DomainObject{
    DomainT Get(Object id);
}

然后是具体的实现

public class ThreadRepository : Repository<Thread>{
    public Order Get(Object id){
         return _session.Find(typeof(Thread),id);
    }
}

现在我的问题是,一个线程可以有很多帖子,比如StackOverflow,让我们说这个帖子有300个帖子.使用上面的语句,我将获得Thread对象,而我只想显示20个项目的列表,因此我将访问Thread对象的Post Collection属性,由于LazyLoading将获取所有300个,准备让我处理我多么高兴.

调用Repository上的方法会更有效吗?

GetThreadPosts(object threadID, int pageSize, int index);
GetThreadPostCount(object threadID);

或者二级缓存会使这个调用相对便宜,就像回到300个帖子一样,保留我的域模型.

>如果有3000或30,000个帖子,那么Thread Domain Model上的Post Collection属性是否仍然有效?
>如果最好有GetThreadPosts& GetThreadPostCount,这是否意味着List的Thread对象上的属性是多余的?
>如果对象上的List属性只有在可能具有的项目数量不会超过某个数字的情况下才可行时,我是否应该有一个限制?

谢谢你的时间,

安德鲁

最佳答案 延迟加载的工作方式是它将推迟执行数据库连接查询,直到您访问Posts集合.现在,如果您要在页面上仅显示30个帖子,而数据库中有30000个帖子符合您的标准,则加载所有收集将是一种浪费.

在我看来,分页应该在数据库级别完成.在这种情况下,我将从Thread类中删除Posts集合,Post应该属于一个允许您构造查询的Thread.此外,single方法足以获取分页帖子集合和帖子总数:

public IEnumerable<Post> GetPosts(object threadID, int pageSize, int index, out totalPosts) 
{
    var results = session
        .CreateMultiCriteria()
        .Add(GetCriteria(threadID)
             .SetFirstResult((index - 1) * pageSize)
             .SetMaxResults(pageSize)
        )
        .Add(GetCriteria(threadID)
             .SetProjection(Projections.RowCount())
        )
        .List();

    var counts = (IList)results[1];
    totalPosts = (int)counts[0];
    return ((IList)results[0]).Cast<Post>();
}

private DetachedCriteria GetCriteria(object threadID)
{
    return DetachedCriteria
        .For<Post>()
        .Add(Expression.Eq("Thread.Id", threadID));
}
点赞