protected override Expression VisitSubQuery(SubQueryExpression expression) { var subQueryModel = expression.QueryModel; var contains = subQueryModel.ResultOperators.FirstOrDefault() as ContainsResultOperator; // Check if IEnumerable.Contains is used. if (subQueryModel.ResultOperators.Count == 1 && contains != null) { VisitContains(subQueryModel, contains); } else if (_visitEntireSubQueryModel) { ResultBuilder.Append('('); _modelVisitor.VisitQueryModel(subQueryModel, false, true); ResultBuilder.Append(')'); } else { // This happens when New expression uses a subquery, in a GroupBy. _modelVisitor.VisitSelectors(expression.QueryModel, false); } return(expression); }
/// <summary> /// Visits IEnumerable.Contains /// </summary> private void VisitContains(QueryModel subQueryModel, ContainsResultOperator contains) { ResultBuilder.Append("("); var fromExpression = subQueryModel.MainFromClause.FromExpression; var queryable = ExpressionWalker.GetCacheQueryable(fromExpression, false); if (queryable != null) { Visit(contains.Item); ResultBuilder.Append(" IN ("); _modelVisitor.VisitQueryModel(subQueryModel); ResultBuilder.Append(")"); } else { var inValues = GetInValues(fromExpression).ToArray(); var hasNulls = inValues.Any(o => o == null); if (hasNulls) { ResultBuilder.Append("("); } Visit(contains.Item); ResultBuilder.Append(" IN ("); AppendInParameters(inValues); ResultBuilder.Append(")"); if (hasNulls) { ResultBuilder.Append(") OR "); Visit(contains.Item); ResultBuilder.Append(" IS NULL"); } } ResultBuilder.Append(")"); }