2009-07-25 47 views
4

从文本“存储库”模式是域和数据映射器层之间的中介。凉。因此,举例来说,也许有一个仓库接口和基地的域对象,像这样如何使用NHibernate和存储库模式从域对象的属性返回分页列表

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个帖子。使用上面的语句,我将获得线程对象,并且我只想显示20个项目的列表,因此我将访问Thread对象的Post Collection属性,由于LazyLoading将获取所有300个,准备好处理我很高兴。

难道是更有效地对仓库里的方法称为

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

或者将二级缓存拨打这个电话比较便宜,如取回的300个职位,保留我的域模型。

  • 如果有3000或30,000个帖子,Thread Domain Model上的Post Collection属性仍然有效会怎么样?

  • 如果最好有GetThreadPosts & GetThreadPostCount,这是否意味着List的Thread对象的属性是多余的?

  • 是否应该是这样的情况下,我应该有一个限制记住,当一个对象上的List属性是唯一可行的,如果说可能有的项目数量不会超过一定数量?

感谢您的时间,

安德鲁

回答

2

懒加载的工作方式是,将推迟对数据库执行连接查询,直到您访问的帖子集合。现在,如果您要在页面上只显示30个帖子,而数据库中有30000个帖子满足您的条件,那么加载所有收藏将是浪费。

在我看来,分页应该在数据库级完成。在这种情况下,我将从Thread类中移除Posts集合,并且Post应该属于一个允许您构造查询的Thread。另外一个single方法就足以得到分页的Posts集合和帖子总数:

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)); 
} 
+0

感谢您的解释。这听起来非常合逻辑! :-) – 2009-07-25 10:42:16

相关问题