我通常在我的应用程序中使用“Page - > Service - > Repository”模式,将所有数据库调用放在“repository”类中。
在某些情况下,我要在我的服务逻辑中测试收集项目数。
示例:
EventService eventService=container.Resolve<EventService>();
IEnumerable<Event> events=eventService.GetAll();
if(events.Count()>0)
{
...do something...
}
使用NHibernate,这将自动生成一个带有数据库访问权限的SQL语句。
我可以避免这个吗?有最好的做法吗?
答案 0 :(得分:4)
我尝试避免在存储库中公开IQueryable<T>
,原因如下:
相反,我会选择使用一个简单的查询对象,该对象被翻译成存储库所需的任何内容。
特别是对于这种情况,我会在存储库上有一个返回分页事件列表的方法:
IList<Event> GetAll(int startIndex, int count);
这也凸显了分页的重要性。在存储库中,这可能是:
this.Session.Linq<Event>().Skip(startIndex).Take(count).ToList();
您也可以选择为IList创建一个包装对象,它也可以包含总计数。
答案 1 :(得分:1)
如果您(单位)测试您的服务层,那么您应该嘲笑您的存储库。您可以创建一个模拟存储库,其中包含作为IQueryable公开的静态对象列表。
这样当你调用Count()时,它将返回静态列表的计数,你可以可靠地断言。
更新
我的错误,我从这一行开始假设
我要测试收集物品的数量 我的服务逻辑
你想测试你的服务逻辑。
您的上述代码看起来像是在返回IQueryable。因此,只要您调用Count()
或ToList()
(基本上是枚举IQueryable的任何内容),您就会点击数据库。
因此,请更改您的服务以返回IList<T>
或将您的代码更改为以下内容:
EventService eventService=container.Resolve<EventService>();
IEnumerable<Event> events = eventService.GetAll().ToList();
if(events.Count()>0) { ...do something... }
当您致电ToList()
时,您将点击数据库,但在使用内存中集合时调用Count()
时则不会。