2

I am using Entity framework 4 and I have the following piece of code:

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<FinalResult_Base, bool> wherePredicate, bool countSvp)
{
    using (var db = new DataEntities())
    {
        IQueryable<FinalResult_Base> query = db
                  .FinalResult_Bases.Where(wherePredicate).AsQueryable();


        if (!countSvp)
            query = query.Where(x => x.SpecialNeeds == 0);


        query.Any();   //--HERE is created the SELECT with NO WHERE clause
        ....
    }
}

I don't understand why the resulting SELECT statmenet at line query.Any() does not have any WHERE clause. Neither filter from wherePredicate nor x.SpecialNeeds == 0 is applied.

Any idea?

UPDATE 1: The problem seems to be the wherePredicate, which is of type Func not Expression. I will try to use Expression.

Ondrej Peterka
  • 3,349
  • 4
  • 35
  • 49
  • That sounds very odd. Why are you using `AsQueryable` anyway? I wouldn't have expected you to need to, given that you're using EF... – Jon Skeet May 17 '13 at 08:56
  • @Jon Well, I did not write the code to be honest, but I guess it is needed to build the query dynamically. For example to add the `x => x.SpecialNeeds == 0 condition`. Is that not correct? – Ondrej Peterka May 17 '13 at 08:59
  • 1
    IMO `db.FinalResult_Bases.Where(wherePredicate)` is already `IQueryable` so you don't need `.AsQueryable();` – Michal B. May 17 '13 at 09:21
  • Did you step through it with the debugger is countSvp `false`? – TGlatzer May 17 '13 at 09:25
  • @Grumbler85 I have with tried with countSvp both true and false. No effect. – Ondrej Peterka May 17 '13 at 09:47
  • @MichalB. No it is not. When I remove the AsQueryable, the compiler complains as the reuslt is Enumerable. The wherePredicate (as it is Func not Expression) causes using overloaded version of Where method which returns Enumerable. However, this might be the root of the problem. – Ondrej Peterka May 17 '13 at 09:52

1 Answers1

4

Try changing the GetSuccessRate method declaration to

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

The reason is that there are two Where extension methods inside: Enumerable.Where and Queryable.Where and they have different declarations:

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

and

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

so one receives Func<TSource, bool> and another one Expression<Func<TSource, bool>>

After you change your declaration the .AsQueryable() call will not make any difference.

Olexander Ivanitskyi
  • 2,202
  • 17
  • 32
  • +1; I have been just writing the answer ot my own question with very similar content :). I have found out whats going on from these two SO questions: http://stackoverflow.com/questions/2876616/returning-ienumerablet-vs-iqueryablet, http://stackoverflow.com/questions/2664841/difference-between-expressionfunc-and-func – Ondrej Peterka May 17 '13 at 10:10
  • he he, the first question contains my answer in the bottom:) I wish I had time to explain internal details why it happens, but hopefully I'll post it soon. – Olexander Ivanitskyi May 17 '13 at 10:59