背景
我正在使用工作单元/存储库模式处理Web应用程序。我选择了一个与存储库交互的服务层。存储库将 IQueryable 返回到服务层,服务层将 List 返回给控制器。
我决定不将 IQueryable 返回给控制器,以确保查询可以重复使用并放置在适当的层 - 服务层。另外,因为以后可能需要Web服务。
问题
在控制器级别允许分页和排序而不在控制器级别暴露 IQueryable 的最佳方法是什么?
一个选项是向所有可能返回多个实体的服务功能添加参数,但这似乎并不理想。或者,我仍然可以在返回的列表上进行寻呼,但这会导致大量不必要的数据访问。
编辑以澄清
我的存储库具有以下功能:
public IQueryable<T> GetAll()
{
return objectSet;
}
我的服务有以下功能:
public List<Person> GetAllPeople()
{
return repository.GetAll().ToList()
}
我很高兴让存储库将 IQueryable 返回给服务,因为这允许服务具有以下功能:GetPersonByName,GetPersonByEmail等
但是我正在寻找一种替代方法,只需将 GetAllPeople 函数放在'PageNumber'和'PageSize'参数之上。
答案 0 :(得分:2)
绝对最有效地将您的分页实现为尽可能靠近底层商店。考虑到这一点,我认为在服务层方法中接受分页参数是值得的。
我的0.02美元:这是一个理论不应该胜过实用性的案例。
答案 1 :(得分:1)
如果我理解你的问题,这是一个解决方案: 您可以在任何IQueryable上调用AsEnumerable(),后续操作将使用Enumerable(LINQ to Objects)实现,而不是Queryable版本。
我在MSDN上写了很多详细信息:http://msdn.microsoft.com/en-us/vcsharp/ff963710
答案 2 :(得分:0)
我曾经遇到过类似的问题,并撰写了一篇关于它的博客文章here
您的情况并不完全相同,但存储库模式的概念和限制是。
基本上我选择做的是用查询对象模式替换存储库模式。查询对象保存了用于过滤,排序和分页的参数,然后在服务级别包含了IQueryable。
这样我的控制器和服务层之间就有了一致的界面,如果我改变数据存储就不需要改变(如果你以后离开LINQ包装的商店怎么办?)并控制多少IQueryable暴露无遗。
答案 3 :(得分:0)
您可以为IQueryable
结果创建一个包装器,这样您就只能进行分页和排序。解释in this article之类的东西。但我建议将那里提出的两个接口(ISortable
和IPageable
)合并到一个包装器中。