实体框架高效查询过滤器

时间:2012-02-13 11:51:59

标签: .net entity-framework entity-framework-4

在我的mvc网站中,我使用EF 4.1进行数据访问。现在我开发产品搜索功能。获取过滤产品的方法签名是:

PagedList<Dress> GetDressesPage<TKey>(int page, int dressesPerPage, Func<Dress, bool> selection, Func<Dress, TKey> order, SortDirection direction);

以及我获得产品的方式是:

dresses = _context.Dresses.Where(selection).OrderBy(order).Skip(page * dressesPerPage).Take(dressesPerPage).ToList();

问题在于选择功能。我希望能够通过附加不同的条件来构建它。现在我正在为每个参数组合使用一些if子句构建它...但是这太复杂了。

您是否知道我可以将过滤器作为参数传递的简单方法?

2 个答案:

答案 0 :(得分:4)

使用Predicate Builder。将Func<Dress, bool>替换为Expression<Func<Dress, bool>>。否则,查询将变为LINQ-to-Objects。

  var predicate = PredicateBuilder.True<Dress>();
  if (!string.IsNullOrEmpty(name))
  {
       predicate = predicate.And(d => d.Name.Contains(name));
  }

  dresses = _context.Dresses.Where(predicate).OrderBy(order)
      .Skip(page * dressesPerPage).Take(dressesPerPage).ToList();

答案 1 :(得分:0)

一个完美的图书馆是“LinqKit”。

使用示例:

    public static IEnumerable<DressItem> QueryDresses(FashionEntities ctx, Expression<Func<dresses, bool>> predicate)
    {
        var query = (from dress in ctx.dresses
                         .AsExpandable()
                         .Where(predicate)                    
                  select new DressItem { 
                      id = dress.Id, 
                      name = dress.Name, 
                      price = dress.Price 
                  };
        return query;
    }

如您所见,该方法接受一个可以在调用方法中构造的谓词,如下所示:

  Expression<Func<dresses, bool>> predicate = d => d.Price > 1000;

  if (lalalala == llalala) {
      predicate = d => d.Price > 2000;
  }

  var result = new List<DressItem>();
  using (var ctx = new FashionEntities())
  {
       var dresses = QueryDresses(ctx, predicate.Expand());
       result = dresses.ToList();
  }