protected virtual Expression VisitExists(ExistsExpression exists) { var select = (SelectExpression)this.Visit(exists.Select); return this.UpdateExists(exists, select); }
protected ExistsExpression UpdateExists(ExistsExpression exists, SelectExpression select) { if (select != exists.Select) { return new ExistsExpression(select); } return exists; }
protected override Expression VisitExists(ExistsExpression exists) { this.Write("EXISTS("); this.WriteLine(Indentation.Inner); this.Visit(exists.Select); this.WriteLine(Indentation.Same); this.Write(")"); this.Indent(Indentation.Outer); return exists; }
protected virtual bool CompareExists(ExistsExpression a, ExistsExpression b) { return this.Compare(a.Select, b.Select); }
private Expression BindAnyAll(Expression source, MethodInfo method, LambdaExpression predicate, bool isRoot) { bool isAll = method.Name == "All"; ConstantExpression constSource = source as ConstantExpression; if (constSource != null && !IsQuery(constSource)) { System.Diagnostics.Debug.Assert(!isRoot); Expression where = null; foreach (object value in (IEnumerable)constSource.Value) { Expression expr = Expression.Invoke(predicate, Expression.Constant(value, predicate.Parameters[0].Type)); if (where == null) { where = expr; } else if (isAll) { where = where.And(expr); } else { where = where.Or(expr); } } return this.Visit(where); } else { if (isAll) { predicate = Expression.Lambda(Expression.Not(predicate.Body), predicate.Parameters.ToArray()); } if (predicate != null) { source = Expression.Call(typeof(Enumerable), "Where", method.GetGenericArguments(), source, predicate); } ProjectionExpression projection = this.VisitSequence(source); Expression result = new ExistsExpression(projection.Select); if (isAll) { result = Expression.Not(result); } if (isRoot) { if (this.language.AllowSubqueryInSelectWithoutFrom) { return GetSingletonSequence(result, "SingleOrDefault"); } else { // use count aggregate instead of exists var colType = this.language.TypeSystem.GetStorageType(typeof(int)); var newSelect = projection.Select.SetFields( new[] { new FieldDeclaration("value", new AggregateExpression(typeof(int), "Count", null, false), colType) } ); var colx = new FieldExpression(typeof(int), colType, newSelect.Alias, "value"); var exp = isAll ? colx.Equal(Expression.Constant(0)) : colx.GreaterThan(Expression.Constant(0)); return new ProjectionExpression( newSelect, exp, Aggregator.GetAggregator(typeof(bool), typeof(IEnumerable<bool>)) ); } } return result; } }
protected virtual Expression BindIntersect(Expression outerSource, Expression innerSource, bool negate) { // SELECT * FROM outer WHERE EXISTS(SELECT * FROM inner WHERE inner = outer)) ProjectionExpression outerProjection = this.VisitSequence(outerSource); ProjectionExpression innerProjection = this.VisitSequence(innerSource); Expression exists = new ExistsExpression( new SelectExpression(new IdentifiableAlias(), null, innerProjection.Select, innerProjection.Projector.Equal(outerProjection.Projector)) ); if (negate) exists = Expression.Not(exists); var alias = this.GetNextAlias(); ProjectedFields pc = this.ProjectFields(outerProjection.Projector, alias, outerProjection.Select.Alias); return new ProjectionExpression( new SelectExpression(alias, pc.Fields, outerProjection.Select, exists), pc.Projector, outerProjection.Aggregator ); }