在存储库模式中使用IQueryable <T>的替代方法是什么?

mat*_*i82 1 entity-framework iqueryable repository-pattern

我是ASP.NET MVC新手(但.NET经验丰富的开发者),我正在努力学习如何正确设置Web应用程序基础结构.存储库模式是我现在正在考虑的,在过去几天阅读了几十篇博客/文章/答案后,我仍然不确定如何以正确的方式使用它.我正在学习Pro ASP.NET MVC 4 Adam Freeman,这里是基于本书的存储库接口代码:

public interface IRepository<T>
{
    IQueryable<T> FindAll();
    IQueryable<T> Find(Expression<Func<T, bool>> predicate);

    void Add(T newEntity);
    void Remove(T entity);

    T FindById(long id);
}
Run Code Online (Sandbox Code Playgroud)

经过更多的在线研究,我意识到许多人认为从存储库中返回IQueryable是不好的做法,我(大多数时候)可以理解为什么.但是,我似乎无法找到具体替代方案的答案?我知道有一个自定义存储库的想法,对于每个实体,每个可能的查询都有专门的方法,基本上会返回IEnumerable而不是IQueryable ......但这对我来说似乎不对(它也不是优雅的解决方案)许多代码编写和可能的代码冗余等...).

还有什么其他选择?

jga*_*fin 7

你有两种选择.

规格图案

第一个是使用规范模式.您创建一组用于限制搜索结果的类.

维基百科文章有点差,因为它没有显示如何编写业务规范(即"真实"规范).但是你基本上在业务规范中使用较低级别的规范(和/或等).

通过这样做,您可以拥有更简单的存储库类,而不是编写这些规范.

特定的存储库.

为每个根聚合(订单,用户等)创建存储库.每个存储库都具有适用于特定业务需求的唯一查询方法.

例如,用户存储库可以具有

IPagedResult<User> FindDisabledUser(int pageNumber, int pageSize);
Run Code Online (Sandbox Code Playgroud)

订单存储库可以有

IPagedResult<User> GetOrdersReadyForShipping(DateTime orderAfterThisDate);
Run Code Online (Sandbox Code Playgroud)

我写了一组数据层文章:http://blog.gauffin.org/tag/data-access/.其中一个也解释了为什么IQueryable<T>在您的存储库中公开不是一个好主意.