public ISqlPredicate Reduce() { var predicate = new ExprExpr(Expr1, Operator.Equal, IsNot ? FalseValue : TrueValue); if (WithNull == null) { return(predicate); } var search = new SqlSearchCondition(); search.Conditions.Add(new SqlCondition(false, predicate, WithNull.Value)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr1, !WithNull.Value), WithNull.Value)); return(search); }
protected override ICloneableElement Clone(Dictionary <ICloneableElement, ICloneableElement> objectTree, Predicate <ICloneableElement> doClone) { if (!doClone(this)) { return(this); } if (!objectTree.TryGetValue(this, out var clone)) { objectTree.Add(this, clone = new ExprExpr( (ISqlExpression)Expr1.Clone(objectTree, doClone), Operator, (ISqlExpression)Expr2.Clone(objectTree, doClone))); } return(clone); }
private static void BuildSubQueryJoin( ExpressionBuilder builder, IBuildContext outerKeyContext, Expression outerKeySelector, Expression innerKeySelector, IBuildContext subQueryKeyContext, ISelectQuery subQuerySelect) { var predicate = builder.ConvertObjectComparison( ExpressionType.Equal, outerKeyContext, outerKeySelector, subQueryKeyContext, innerKeySelector); if (predicate == null) { predicate = new ExprExpr( builder.ConvertToSql(outerKeyContext, outerKeySelector), EOperator.Equal, builder.ConvertToSql(subQueryKeyContext, innerKeySelector)); predicate = builder.Convert(outerKeyContext, predicate); } subQuerySelect.Where.Search.Conditions.AddLast(new Condition(false, predicate)); }
private static void BuildJoin( ExpressionBuilder builder, IJoin join, IBuildContext outerKeyContext, Expression outerKeySelector, IBuildContext innerKeyContext, Expression innerKeySelector) { var predicate = builder.ConvertObjectComparison( ExpressionType.Equal, outerKeyContext, outerKeySelector, innerKeyContext, innerKeySelector); if (predicate == null) { predicate = new ExprExpr( builder.ConvertToSql(outerKeyContext, outerKeySelector), EOperator.Equal, builder.ConvertToSql(innerKeyContext, innerKeySelector)); predicate = builder.Convert(outerKeyContext, predicate); } join.JoinedTable.Condition.Conditions.AddLast(new Condition(false, predicate)); }
public ISqlPredicate Reduce() { if (Expr1.ElementType == QueryElementType.SearchCondition) { if (!IsNot) { return((ISqlPredicate)Expr1); } return(new SqlSearchCondition(new SqlCondition(true, (ISqlPredicate)Expr1))); } var predicate = new ExprExpr(Expr1, Operator.Equal, IsNot ? FalseValue : TrueValue, null); if (WithNull == null || !Expr1.ShouldCheckForNull()) { return(predicate); } var search = new SqlSearchCondition(); search.Conditions.Add(new SqlCondition(false, predicate, WithNull.Value)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr1, !WithNull.Value), WithNull.Value)); return(search); }
public ISqlPredicate Reduce(EvaluationContext context) { if (Operator == Operator.Equal || Operator == Operator.NotEqual) { if (Expr1.TryEvaluateExpression(context, out var value1)) { if (value1 == null) { return(new IsNull(Expr2, Operator != Operator.Equal)); } } else if (Expr2.TryEvaluateExpression(context, out var value2)) { if (value2 == null) { return(new IsNull(Expr1, Operator != Operator.Equal)); } } } if (WithNull == null) { return(this); } var canBeNull_1 = Expr1.ShouldCheckForNull(); var canBeNull_2 = Expr2.ShouldCheckForNull(); var isInverted = !WithNull.Value; var predicate = new ExprExpr(Expr1, Operator, Expr2, null); if (!canBeNull_1 && !canBeNull_2) { return(predicate); } var search = new SqlSearchCondition(); if (Expr1.CanBeEvaluated(context)) { if (!Expr2.CanBeEvaluated(context)) { if (canBeNull_2) { if (isInverted) { if (Operator != Operator.Equal) { search.Conditions.Add(new SqlCondition(false, predicate, true)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr2, false), false)); } } else if (Operator == Operator.NotEqual) { search.Conditions.Add(new SqlCondition(false, predicate, true)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr2, false), false)); } } } } else if (Expr2.CanBeEvaluated(context)) { if (canBeNull_1) { if (isInverted) { if (Operator != Operator.Equal) { search.Conditions.Add(new SqlCondition(false, predicate, true)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr1, false), false)); } } else if (Operator == Operator.NotEqual) { search.Conditions.Add(new SqlCondition(false, predicate, true)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr1, false), false)); } } } else { if (canBeNull_2) { if (canBeNull_1) { if (isInverted) { if (Operator == Operator.Equal) { search.Conditions.Add(new SqlCondition(false, predicate, true)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr1, false), false)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr2, true), true)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr1, true), false)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr2, false), false)); } else if (Operator == Operator.NotEqual) { search.Conditions.Add(new SqlCondition(false, predicate, true)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr1, false), false)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr2, true), true)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr1, true), false)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr2, false), false)); } else if (Operator == Operator.LessOrEqual || Operator == Operator.GreaterOrEqual) { search.Conditions.Add(new SqlCondition(false, predicate, true)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr1, false), true)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr2, false), false)); } else { search.Conditions.Add(new SqlCondition(false, predicate, true)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr1, false), false)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr2, false), false)); } } else if (Operator == Operator.Equal) { search.Conditions.Add(new SqlCondition(false, predicate, true)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr1, false), false)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr2, false), false)); } else if (Operator == Operator.NotEqual) { search.Conditions.Add(new SqlCondition(false, predicate, true)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr1, false), false)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr2, true), true)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr1, true), false)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr2, false), false)); } } else if (isInverted) { search.Conditions.Add(new SqlCondition(false, predicate, true)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr2, false), false)); } } else { if (canBeNull_1) { if (isInverted) { search.Conditions.Add(new SqlCondition(false, predicate, true)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr1, false), false)); } } else { search.Conditions.Add(new SqlCondition(false, predicate, true)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr1, false), false)); search.Conditions.Add(new SqlCondition(false, new IsNull(Expr2, false), false)); } } } if (search.Conditions.Count == 0) { return(predicate); } return(search); }
private IQueryElement ConvertInternal(IQueryElement element, Func <IQueryElement, IQueryElement> action) { if (element == null) { return(null); } IQueryElement newElement; if (_visitedElements.TryGetValue(element, out newElement)) { return(newElement); } switch (element.ElementType) { case EQueryElementType.SqlFunction: { var func = (ISqlFunction)element; var parms = Convert(func.Parameters, action); if (parms != null && !ReferenceEquals(parms, func.Parameters)) { newElement = new SqlFunction(func.SystemType, func.Name, func.Precedence, parms); } break; } case EQueryElementType.SqlExpression: { var expr = (ISqlExpression)element; var parameter = Convert(expr.Parameters, action); if (parameter != null && !ReferenceEquals(parameter, expr.Parameters)) { newElement = new SqlExpression(expr.SystemType, expr.Expr, expr.Precedence, parameter); } break; } case EQueryElementType.SqlBinaryExpression: { var bexpr = (ISqlBinaryExpression)element; var expr1 = (IQueryExpression)ConvertInternal(bexpr.Expr1, action); var expr2 = (IQueryExpression)ConvertInternal(bexpr.Expr2, action); if (expr1 != null && !ReferenceEquals(expr1, bexpr.Expr1) || expr2 != null && !ReferenceEquals(expr2, bexpr.Expr2)) { newElement = new SqlBinaryExpression(bexpr.SystemType, expr1 ?? bexpr.Expr1, bexpr.Operation, expr2 ?? bexpr.Expr2, bexpr.Precedence); } break; } case EQueryElementType.SqlTable: { var table = (ISqlTable)element; var fields1 = ToArray(table.Fields); var fields2 = Convert(fields1, action, f => new SqlField(f)); var targs = table.TableArguments == null ? null : Convert(table.TableArguments, action); var fe = fields2 == null || ReferenceEquals(fields1, fields2); var ta = ReferenceEquals(table.TableArguments, targs); if (!fe || !ta) { if (fe) { fields2 = fields1; for (var i = 0; i < fields2.Length; i++) { var field = fields2[i]; fields2[i] = new SqlField(field); _visitedElements[field] = fields2[i]; } } newElement = new SqlTable(table, fields2, targs ?? table.TableArguments); } break; } case EQueryElementType.Column: { var col = (IColumn)element; var expr = (IQueryExpression)ConvertInternal(col.Expression, action); IQueryElement parent; _visitedElements.TryGetValue(col.Parent, out parent); if (parent != null || expr != null && !ReferenceEquals(expr, col.Expression)) { newElement = new Column(parent == null ? col.Parent : (ISelectQuery)parent, expr ?? col.Expression, col.Alias); } break; } case EQueryElementType.TableSource: { var table = (ITableSource)element; var source = (ISqlTableSource)ConvertInternal(table.Source, action); var joins = Convert(table.Joins, action); if (source != null && !ReferenceEquals(source, table.Source) || joins != null && !ReferenceEquals(table.Joins, joins)) { newElement = new TableSource(source ?? table.Source, table.Alias, joins ?? table.Joins); } break; } case EQueryElementType.JoinedTable: { var join = (IJoinedTable)element; var table = (ITableSource)ConvertInternal(join.Table, action); var cond = (ISearchCondition)ConvertInternal(join.Condition, action); if (table != null && !ReferenceEquals(table, join.Table) || cond != null && !ReferenceEquals(cond, join.Condition)) { newElement = new JoinedTable(join.JoinType, table ?? join.Table, join.IsWeak, cond ?? join.Condition); } break; } case EQueryElementType.SearchCondition: { var sc = (ISearchCondition)element; var conds = Convert(sc.Conditions, action); if (conds != null && !ReferenceEquals(sc.Conditions, conds)) { newElement = new SearchCondition(conds); } break; } case EQueryElementType.Condition: { var c = (Condition)element; var p = (ISqlPredicate)ConvertInternal(c.Predicate, action); if (p != null && !ReferenceEquals(c.Predicate, p)) { newElement = new Condition(c.IsNot, p, c.IsOr); } break; } case EQueryElementType.ExprPredicate: { var p = (IExpr)element; var e = (IQueryExpression)ConvertInternal(p.Expr1, action); if (e != null && !ReferenceEquals(p.Expr1, e)) { newElement = new Expr(e, p.Precedence); } break; } case EQueryElementType.NotExprPredicate: { var p = (INotExpr)element; var e = (IQueryExpression)ConvertInternal(p.Expr1, action); if (e != null && !ReferenceEquals(p.Expr1, e)) { newElement = new NotExpr(e, p.IsNot, p.Precedence); } break; } case EQueryElementType.ExprExprPredicate: { var p = (IExprExpr)element; var e1 = (IQueryExpression)ConvertInternal(p.Expr1, action); var e2 = (IQueryExpression)ConvertInternal(p.Expr2, action); if (e1 != null && !ReferenceEquals(p.Expr1, e1) || e2 != null && !ReferenceEquals(p.Expr2, e2)) { newElement = new ExprExpr(e1 ?? p.Expr1, p.EOperator, e2 ?? p.Expr2); } break; } case EQueryElementType.LikePredicate: { var p = (ILike)element; var e1 = (IQueryExpression)ConvertInternal(p.Expr1, action); var e2 = (IQueryExpression)ConvertInternal(p.Expr2, action); var es = (IQueryExpression)ConvertInternal(p.Escape, action); if (e1 != null && !ReferenceEquals(p.Expr1, e1) || e2 != null && !ReferenceEquals(p.Expr2, e2) || es != null && !ReferenceEquals(p.Escape, es)) { newElement = new Like(e1 ?? p.Expr1, p.IsNot, e2 ?? p.Expr2, es ?? p.Escape); } break; } case EQueryElementType.HierarhicalPredicate: { var p = (IHierarhicalPredicate)element; var e1 = (IQueryExpression)ConvertInternal(p.Expr1, action); var e2 = (IQueryExpression)ConvertInternal(p.Expr2, action); if (e1 != null && !ReferenceEquals(p.Expr1, e1) || e2 != null && !ReferenceEquals(p.Expr2, e2)) { newElement = new HierarhicalPredicate(e1 ?? p.Expr1, e2 ?? p.Expr2, p.Flow); } break; } case EQueryElementType.BetweenPredicate: { var p = (IBetween)element; var e1 = (IQueryExpression)ConvertInternal(p.Expr1, action); var e2 = (IQueryExpression)ConvertInternal(p.Expr2, action); var e3 = (IQueryExpression)ConvertInternal(p.Expr3, action); if (e1 != null && !ReferenceEquals(p.Expr1, e1) || e2 != null && !ReferenceEquals(p.Expr2, e2) || e3 != null && !ReferenceEquals(p.Expr3, e3)) { newElement = new Between(e1 ?? p.Expr1, p.IsNot, e2 ?? p.Expr2, e3 ?? p.Expr3); } break; } case EQueryElementType.IsNullPredicate: { var p = (IIsNull)element; var e = (IQueryExpression)ConvertInternal(p.Expr1, action); if (e != null && !ReferenceEquals(p.Expr1, e)) { newElement = new IsNull(e, p.IsNot); } break; } case EQueryElementType.InSubQueryPredicate: { var p = (IInSubQuery)element; var e = (IQueryExpression)ConvertInternal(p.Expr1, action); var q = (ISelectQuery)ConvertInternal(p.SubQuery, action); if (e != null && !ReferenceEquals(p.Expr1, e) || q != null && !ReferenceEquals(p.SubQuery, q)) { newElement = new InSubQuery(e ?? p.Expr1, p.IsNot, q ?? p.SubQuery); } break; } case EQueryElementType.InListPredicate: { var p = (IInList)element; var e = (IQueryExpression)ConvertInternal(p.Expr1, action); var v = Convert(p.Values, action); if (e != null && !ReferenceEquals(p.Expr1, e) || v != null && !ReferenceEquals(p.Values, v)) { newElement = new InList(e ?? p.Expr1, p.IsNot, v ?? p.Values); } break; } case EQueryElementType.FuncLikePredicate: { var p = (IFuncLike)element; var f = (ISqlFunction)ConvertInternal(p.Function, action); if (f != null && !ReferenceEquals(p.Function, f)) { newElement = new FuncLike(f); } break; } case EQueryElementType.SetExpression: { var s = (ISetExpression)element; var c = (IQueryExpression)ConvertInternal(s.Column, action); var e = (IQueryExpression)ConvertInternal(s.Expression, action); if (c != null && !ReferenceEquals(s.Column, c) || e != null && !ReferenceEquals(s.Expression, e)) { newElement = new SetExpression(c ?? s.Column, e ?? s.Expression); } break; } case EQueryElementType.InsertClause: { var s = (IInsertClause)element; var t = s.Into != null ? (ISqlTable)ConvertInternal(s.Into, action) : null; var i = Convert(s.Items, action); if (t != null && !ReferenceEquals(s.Into, t) || i != null && !ReferenceEquals(s.Items, i)) { var sc = new InsertClause { Into = t ?? s.Into }; (i ?? s.Items).ForEach(node => sc.Items.AddLast(node.Value)); sc.WithIdentity = s.WithIdentity; newElement = sc; } break; } case EQueryElementType.UpdateClause: { var s = (IUpdateClause)element; var t = s.Table != null ? (ISqlTable)ConvertInternal(s.Table, action) : null; var i = Convert(s.Items, action); var k = Convert(s.Keys, action); if (t != null && !ReferenceEquals(s.Table, t) || i != null && !ReferenceEquals(s.Items, i) || k != null && !ReferenceEquals(s.Keys, k)) { var sc = new UpdateClause { Table = t ?? s.Table }; (i ?? s.Items).ForEach(node => sc.Items.AddLast(node.Value)); (k ?? s.Keys).ForEach(node => sc.Keys.AddLast(node.Value)); newElement = sc; } break; } case EQueryElementType.DeleteClause: { var s = (IDeleteClause)element; var t = s.Table != null ? (ISqlTable)ConvertInternal(s.Table, action) : null; if (t != null && !ReferenceEquals(s.Table, t)) { newElement = new DeleteClause { Table = t }; } break; } case EQueryElementType.CreateTableStatement: { var s = (ICreateTableStatement)element; var t = s.Table != null ? (ISqlTable)ConvertInternal(s.Table, action) : null; if (t != null && !ReferenceEquals(s.Table, t)) { newElement = new CreateTableStatement { Table = t, IsDrop = s.IsDrop }; } break; } case EQueryElementType.SelectClause: { var sc = (ISelectClause)element; var cols = Convert(sc.Columns, action); var take = (IQueryExpression)ConvertInternal(sc.TakeValue, action); var skip = (IQueryExpression)ConvertInternal(sc.SkipValue, action); IQueryElement parent; _visitedElements.TryGetValue(sc.SelectQuery, out parent); if (parent != null || cols != null && !ReferenceEquals(sc.Columns, cols) || take != null && !ReferenceEquals(sc.TakeValue, take) || skip != null && !ReferenceEquals(sc.SkipValue, skip)) { newElement = new SelectClause(sc.IsDistinct, take ?? sc.TakeValue, skip ?? sc.SkipValue, cols ?? sc.Columns); ((ISelectClause)newElement).SetSqlQuery((ISelectQuery)parent); } break; } case EQueryElementType.FromClause: { var fc = (IFromClause)element; var ts = Convert(fc.Tables, action); IQueryElement parent; _visitedElements.TryGetValue(fc.SelectQuery, out parent); if (parent != null || ts != null && !ReferenceEquals(fc.Tables, ts)) { newElement = new FromClause(ts ?? fc.Tables); ((IFromClause)newElement).SetSqlQuery((ISelectQuery)parent); } break; } case EQueryElementType.WhereClause: { var wc = (IWhereClause)element; var cond = (ISearchCondition)ConvertInternal(wc.Search, action); IQueryElement parent; _visitedElements.TryGetValue(wc.SelectQuery, out parent); if (parent != null || cond != null && !ReferenceEquals(wc.Search, cond)) { newElement = new WhereClause(cond ?? wc.Search); ((IWhereClause)newElement).SetSqlQuery((ISelectQuery)parent); } break; } case EQueryElementType.GroupByClause: { var gc = (IGroupByClause)element; var es = Convert(gc.Items, action); IQueryElement parent; _visitedElements.TryGetValue(gc.SelectQuery, out parent); if (parent != null || es != null && !ReferenceEquals(gc.Items, es)) { newElement = new GroupByClause(es ?? gc.Items); ((IGroupByClause)newElement).SetSqlQuery((ISelectQuery)parent); } break; } case EQueryElementType.OrderByClause: { var oc = (IOrderByClause)element; var es = Convert(oc.Items, action); IQueryElement parent; _visitedElements.TryGetValue(oc.SelectQuery, out parent); if (parent != null || es != null && !ReferenceEquals(oc.Items, es)) { newElement = new OrderByClause(es ?? oc.Items); ((IOrderByClause)newElement).SetSqlQuery((ISelectQuery)parent); } break; } case EQueryElementType.OrderByItem: { var i = (IOrderByItem)element; var e = (IQueryExpression)ConvertInternal(i.Expression, action); if (e != null && !ReferenceEquals(i.Expression, e)) { newElement = new OrderByItem(e, i.IsDescending); } break; } case EQueryElementType.Union: { var u = (IUnion)element; var q = (ISelectQuery)ConvertInternal(u.SelectQuery, action); if (q != null && !ReferenceEquals(u.SelectQuery, q)) { newElement = new Union(q, u.IsAll); } break; } case EQueryElementType.SqlQuery: { var q = (ISelectQuery)element; IQueryElement parent = null; var doConvert = false; if (q.ParentSelect != null) { if (!_visitedElements.TryGetValue(q.ParentSelect, out parent)) { doConvert = true; parent = q.ParentSelect; } } if (!doConvert) { doConvert = null != FindFirstOrDefault <IQueryElement>(q, e => { if (_visitedElements.ContainsKey(e) && _visitedElements[e] != e) { return(true); } var ret = action(e); if (ret != null && !ReferenceEquals(e, ret)) { _visitedElements.Add(e, ret); return(true); } return(false); }); } if (!doConvert) { break; } var nq = new SelectQuery { EQueryType = q.EQueryType }; _visitedElements.Add(q, nq); var fc = (IFromClause)ConvertInternal(q.From, action) ?? q.From; var sc = (ISelectClause)ConvertInternal(q.Select, action) ?? q.Select; var ic = q.IsInsert ? ((IInsertClause)ConvertInternal(q.Insert, action) ?? q.Insert) : null; var uc = q.IsUpdate ? ((IUpdateClause)ConvertInternal(q.Update, action) ?? q.Update) : null; var dc = q.IsDelete ? ((IDeleteClause)ConvertInternal(q.Delete, action) ?? q.Delete) : null; var wc = (IWhereClause)ConvertInternal(q.Where, action) ?? q.Where; var gc = (IGroupByClause)ConvertInternal(q.GroupBy, action) ?? q.GroupBy; var hc = (IWhereClause)ConvertInternal(q.Having, action) ?? q.Having; var oc = (IOrderByClause)ConvertInternal(q.OrderBy, action) ?? q.OrderBy; var us = q.HasUnion ? Convert(q.Unions, action) : q.Unions; var ps = new List <ISqlParameter>(q.Parameters.Count); foreach (var p in q.Parameters) { IQueryElement e; if (_visitedElements.TryGetValue(p, out e)) { if (e == null) { ps.Add(p); } else { var sqlParameter = e as ISqlParameter; if (sqlParameter != null) { ps.Add(sqlParameter); } } } } nq.Init(ic, uc, dc, sc, fc, wc, gc, hc, oc, us, (ISelectQuery)parent, q.CreateTable, q.IsParameterDependent, ps); _visitedElements[q] = action(nq) ?? nq; return(nq); } } newElement = newElement == null ? action(element) : (action(newElement) ?? newElement); _visitedElements.Add(element, newElement); return(newElement); }