将 IEnumerable 转换为 IQueryable 是否枚举查询

Does converting an IEnumerable to IQueryable enumerate the query

我正在使用 JQuery 小部件的数据table 在具有服务器端分页、排序和过滤功能的 MVC 应用程序中有一个 table 控件。在进行过滤时,我有以下方法:

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;
}

我正在使用谓词来链接 Or 条件。我显然想要 return 一个 IQueryable 以便在我到达部分之前查询不是 运行:

dbResult = dbResult.Skip(pagesize * pagenum).Take(pagesize);

虽然谓词的结果是 IEnumerable。这就是为什么我称 .AsQueryable();

我担心但不知道的是,如果我是有道理。

在所有这一切中,我假设如果我 return 一个 IEnumerable,它将执行查询。

返回 IEnumerable 本身并不意味着您实际上正在执行查询。这取决于 IEnumerable 的创建者,但通常 IEnumerable 被认为是 惰性 ,并且仅在枚举 IEnumerator 时才触及基础数据源。 Linq 运算符和扩展方法表现良好,因此您的 AsQueryable() 调用不会枚举目标,您应该是安全的。

顺便说一句,您是否尝试过更改您的代码:

Func<ImportRfqViewModel, bool> funcOr = l => orResultPredicate(l);

对此(当然,只要您的查询提供程序完全支持 Where 和您正在构建的谓词)?

Expression<Func<ImportRfqViewModel, bool>> funcOr = ...;

这样你应该能够避免在 IQueryableIEnumerable 之间来回切换,你根本不需要调用 AsQueryable(),因此你没有更多疑惑。如果你的查询提供者支持它,它会比你现在做的更有效率,它会在查询底层数据源后执行过滤。

编辑:为了更清楚,从 Func<>Expression<> 的移动不仅仅是改变变量类型的问题,这实际上意味着您必须回顾构建谓词的整个过程,以便您始终通过组合 Expression 个实例来工作,而不仅仅是 Func 个实例,否则您的结果表达式树将很难理解您的查询提供者。