.NET存储库模式通用查询方法

时间:2015-06-25 02:07:21

标签: c# entity-framework repository iqueryable specification-pattern

我正在使用Repository模式,我有一个基础存储库,我使用Entity Framework和web api; 我的问题是我想让我的客户能够动态查询任何数据;类似于查询表达式和获取Dynamics CRM中使用的xml; 我尝试了规范模式,但这还不够,因为我想允许客户端代码订购具有不同列的数据,例如命名为asc Address desc,并且允许对返回的结果进行分页;因此我的方法要求是

  1. 我可能不依赖于ORM技术的通用过滤器 将来更改实体框架
  2. 通用排序方法;允许多个排序列,例如 名称asc地址desc
  3. 客户端确定返回的列或所有列,例如 columnSet为“地址,名称和ID”或返回整个记录
  4. 允许分页,例如页面索引和页面大小
  5. 支持返回记录数量的阈值 结果可能会影响绩效
  6. 这是我最初的方法,但我不知道它是否更好

    IList<TEntity> AllMatching(ISpecification<TEntity> specification = null,
                    Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
                    IList<Expression<Func<TEntity, object>>> includes = null,
                    int? pageIndex = null, int? pageCount = null);
    

1 个答案:

答案 0 :(得分:2)

你可以开始这样做:

 public IQueryable<TEntity> Select(
 Expression<Func<TEntity, bool>> filter = null,
 Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
 IList<Expression<Func<TEntity, object>>> includes = null,
 int? page = null,
 int? pageSize = null)
 {
        IQueryable<TEntity> query = _dbSet;

        if (includes != null)
        {
            query = includes.Aggregate(query, (current, include) => current.Include(include));
        }
        if (orderBy != null)
        {
            query = orderBy(query);
        }
        if (filter != null)
        {
            query = query.AsExpandable().Where(filter);
        }
        if (page != null && pageSize != null)
        {
            query = query.Skip((page.Value - 1)*pageSize.Value).Take(pageSize.Value);
        }
        return query;
 }

正如您所看到的,它几乎可以满足您的所有需求,因此,如果您想在Repository实施中执行相同操作,则必须使用LinqKit nuget包。

如果要选择特定列,可以创建另一种方法,如下所示:

IEnumerable<TResult> AllMatching<TResult>(
Expression<Func<TEntity, TResult>> columns,
Expression<Func<TEntity, bool>> filter = null,
Func<IQueryable<TEntity>, IOrderedQueryable<TEntity>> orderBy = null,
IList<Expression<Func<TEntity, object>>> includes = null,
int? pageIndex = null,
int? pageCount = null)
{
  var query=Select(filter,orderby,includes,page,pageSize);
  return  query.Select(columns);

}