System.NullReferenceException if value of ContainsOperator is null.
Solution: Check for null value, return Expression.Constant (false) if value is null.
Use (string) cast instead of calling ToString method.
refactoring: MethodCallTransformerUtility.CheckConstantExpression should return the constant value so that a cast is not necessary anymore.
Same bug exists in StartsWith/EndsWith transformers.
(from c in Cooks select c).Take ((from k in Kitchen select k).Count())
In this query, the item expression is not searched for subqueries.
This change only affects LINQ providers that extend re-linq by writing their own IExpressionNode/MethodCallExpressionNodeBase implementations.
Previously, subqueries were detected in ExpressionResolver. Now, they're detected in MethodCallExpressionParser. This means that when an argument expression is passed to an expression node parser, subqueries have already been resolved.
This change was introduced because several expression node parsers (e.g., TakeExpressionNode, ContainsExpressionNode, and many others) did not correctly perform sub-query detection on their arguments. Because it was so easy to forget that, it happens automatically now.
For custom node parsers, this means that no manual subquery detection needs to be performed. However, all transformations (e.g., expression visitors) made upon the parsers' arguments must be able to handle SubQueryExpressions, usually by calling QueryModel.TransformExpressions to propagate the transformations to the QueryModel's inner expressions.
Adapt DistinctResultOperatorHandler: Distinct queries do not require ORDER BY clauses because LINQ's Distinct operator allows to reorder the result.
Also add a SQL generation integration test.