为什么在AsQueryable之后紧跟Any会导致选择没有Where子句?
为什么在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(FuncwherePredicate, 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。
问题出现的原因是因为在代码中使用了AsQueryable
方法,然后紧跟着使用了Any
方法,导致了Select
方法中没有Where
子句。
解决方法是将GetSuccessRate
方法的声明更改为如下形式:
private decimal GetSuccessRate( Expression<Func<FinalResult_Base, bool>> wherePredicate, bool countSvp)
这样做的原因是因为在代码中有两个Where
扩展方法,分别是Enumerable.Where
和Queryable.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/…。
希望我能抽出时间解释一下为什么会发生这种情况的内部细节,不过希望我能尽快发布解释。