为什么在AsQueryable之后紧跟Any会导致选择没有Where子句?

23 浏览
0 Comments

为什么在AsQueryable之后紧跟Any会导致选择没有Where子句?

我正在使用Entity Framework 4,并且我有以下一段代码:

public decimal GetSchoolSuccessRate(EvaluationComparationFilter filter)
{
    return this.GetSuccessRate(x => x.TestCampaignId == filter.TestCampaignId &&
                      x.SubjectId == filter.SubjectId &&
                      x.SectionNo == 0, filter.CountSvp);
}
private decimal GetSuccessRate(Func wherePredicate, bool countSvp)
{
    using (var db = new DataEntities())
    {
        IQueryable query = db
                  .FinalResult_Bases.Where(wherePredicate).AsQueryable();
        if (!countSvp)
            query = query.Where(x => x.SpecialNeeds == 0);
        query.Any();   //--在这里创建的SELECT语句没有WHERE子句
        ....
    }
}

我不明白为什么在query.Any()的那行代码中生成的SELECT语句没有任何WHERE子句。既不应用wherePredicate的过滤器,也不应用x.SpecialNeeds == 0的过滤器。

有什么想法吗?

更新1:

问题似乎是wherePredicate的类型为Func而不是Expression。我将尝试使用Expression。

0
0 Comments

问题出现的原因是因为在代码中使用了AsQueryable方法,然后紧跟着使用了Any方法,导致了Select方法中没有Where子句。

解决方法是将GetSuccessRate方法的声明更改为如下形式:

private decimal GetSuccessRate(
    Expression<Func<FinalResult_Base, bool>> wherePredicate, bool countSvp)

这样做的原因是因为在代码中有两个Where扩展方法,分别是Enumerable.WhereQueryable.Where,它们有不同的声明形式:

public static IEnumerable<TSource> Where<TSource>(
    this IEnumerable<TSource> source, 
    Func<TSource, bool> predicate)

public static IQueryable<TSource> Where<TSource>(
    this IQueryable<TSource> source, 
    Expression<Func<TSource, bool>> predicate)

其中一个接受Func<TSource, bool>,另一个接受Expression<Func<TSource, bool>>

在更改了方法声明后,.AsQueryable()方法的调用将不会有任何影响。

这个问题的解决方法来源于两个Stack Overflow的问题:stackoverflow.com/questions/2876616/…stackoverflow.com/questions/2664841/…

希望我能抽出时间解释一下为什么会发生这种情况的内部细节,不过希望我能尽快发布解释。

0