Can a LINQ to SQL IQueryable be unexpectedly evaluated?

纵饮孤独 提交于 2020-01-14 03:58:08

问题


I am writing some code that takes a LINQ to SQL IQueryable<T> and adds further dynamically generated Where clauses. For example here is the skeleton of one of the methods:

IQueryable<T> ApplyContains(IQueryable<T> source, string field, string value)
{
   Expression<Func<T, bool>> lambda;
   ... dynamically generate lambda for p => p.<field>.Contains(value) ...
   return source.Where(lambda);
}

I might chain several of these methods together and finish off with a Skip/Take page.

Am I correct in thinking that when the IQueryable is finally evaluated if there is anything in the lambda expressions that can't be translated to SQL an exception will be thrown? In particular I'm concerned I might accidentally do something that would cause the IQueryable to evaluate early and then continue the evaluation in memory (thereby pulling in thousands of records).

From some things I've read I suspect IQueryable will not evaluate early like this. Can anyone confirm this please?


回答1:


Yes you are correct in thinking that your IQueryable can throw an error at runtime if part of the expression can't be translated into SQL. Because of this I think it's a good idea to have your queries in a Business Layer class (like a data service or repository) and then make sure that query is covered by an automated test.

Regarding your Linq expression evaluating at an unexpected time, the basic rule to keep in mind is that your expression will evaluate whenever you call a foreach on it. This also includes methods that call a foreach behind the scenes like ToList() and FirstOrDefault().

BTW an easy way to tell if a method is going to call a foreach and force your lambda to evaluate is to check whether the return value on that method is an IQueryable. If the return value is another IQueryable then the method is probably just adding to the expression but not forcing it to evaluate. If the return value is a List<T>, an anonymous type, or anything that looks like data instead of an IQueryable then the method had to force your expression to evaluate to get that data.




回答2:


Your thinking is correct.

As long as you pass the IQueryable an Expression in your Where clauses it will not evaluate unexpectedly.

Also, the extension methods beginning with "To" will cause evaluation (i.e. ToList(), ToArray()).



来源:https://stackoverflow.com/questions/4915127/can-a-linq-to-sql-iqueryable-be-unexpectedly-evaluated

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!