在我的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子句。。。但这太复杂了。
你知道一种更简单的方法吗?我可以通过一个过滤器作为参数?
使用谓词生成器。将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();
一个完美的库就是"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();
}