我正在使用JQuery小部件的数据表在MVC应用程序中使用服务器端分页,排序和过滤的表控件。在进行过滤时,我有以下方法:
private IQueryable<ImportRfqViewModel> BuildLinqQuery(System.Collections.Specialized.NameValueCollection query)
{
var result = query.GetValues("filterslength");
var filtersCount = int.Parse(query.GetValues("filterslength")[0]);
if (result == null || filtersCount == 0)
{
return AllImportRfq();
}
Predicate<ImportRfqViewModel> orResultPredicate = PredicateExtensions.False<ImportRfqViewModel>();
for (var i = 0; i < filtersCount; i += 1)
{
var filterValue = query.GetValues("filtervalue" + i)[0].ToUpper();
var filterCondition = query.GetValues("filtercondition" + i)[0];
var filterDataField = query.GetValues("filterdatafield" + i)[0];
var filterOperator = query.GetValues("filteroperator" + i)[0];
if (filterDataField == "ImportRfqId")
{
Predicate<ImportRfqViewModel> predicate = p => p.ImportRfqId.ToString().Contains(filterValue);
orResultPredicate = orResultPredicate.Or(predicate);
}
else if (filterDataField == "DateCreated")
{
Predicate<ImportRfqViewModel> predicate = p => p.DateCreated.ToString("yyyy/MM/dd hh:mm:ss").Contains(filterValue);
orResultPredicate = orResultPredicate.Or(predicate);
}
...
}
Func<ImportRfqViewModel, bool> funcOr = l => orResultPredicate(l);
var allResearch = AllImportRfq().Where(funcOr).AsQueryable();
return allResearch;
}
我正在使用谓词来链接或条件。我显然想要返回一个IQueryable,以便在我到达该部分之前不运行查询:
dbResult = dbResult.Skip(pagesize * pagenum).Take(pagesize);
谓词的结果是IEnumerable
。这就是我调用.AsQueryable();
我关心并且不知道的是,如果我有意义的话,该事物是否可能枚举查询然后返回IQueryable
然后丢弃枚举。
在所有这些中,我假设如果我返回IEnumerable
,它将执行查询。
答案 0 :(得分:2)
单独返回IEnumerable
并不意味着您实际上正在执行查询。这取决于IEnumerable
的创建者,但通常IEnumerable
被视为 lazy ,只有在枚举IEnumerator
时才触及基础数据源。 Linq运算符和扩展方法表现良好,因此AsQueryable()
调用不会枚举目标,您应该是安全的。
Func<ImportRfqViewModel, bool> funcOr = l => orResultPredicate(l);
到此(只要您的查询提供程序完全支持Where
和您正在构建的谓词)?
Expression<Func<ImportRfqViewModel, bool>> funcOr = ...;
通过这种方式,您应该能够避免在IQueryable
和IEnumerable
之间来回走动,您根本不需要调用AsQueryable()
,因此您不会再怀疑。如果您的查询提供程序支持它,它将比您正在执行的操作更有效,这将在查询基础数据源后执行过滤。
编辑:为了让它更清晰,从Func<>
迁移到Expression<>
不仅仅是改变变量的类型,它实际上意味着你' d必须检查构建谓词的整个过程,以便始终通过编写Expression
实例而不只是Func
个实例来工作,否则您的结果表达式树将很难被您的查询提供程序理解。< / p>