예제 #1
0
        public static void ConcatSearchCondition(this SqlWhereClause where, SqlSearchCondition search)
        {
            if (where.IsEmpty)
            {
                where.SearchCondition.Conditions.AddRange(search.Conditions);
            }
            else
            {
                if (where.SearchCondition.Precedence < Precedence.LogicalConjunction)
                {
                    var sc1 = new SqlSearchCondition();

                    sc1.Conditions.AddRange(where.SearchCondition.Conditions);

                    where.SearchCondition.Conditions.Clear();
                    where.SearchCondition.Conditions.Add(new SqlCondition(false, sc1));
                }

                if (search.Precedence < Precedence.LogicalConjunction)
                {
                    var sc2 = new SqlSearchCondition();

                    sc2.Conditions.AddRange(search.Conditions);

                    where.SearchCondition.Conditions.Add(new SqlCondition(false, sc2));
                }
                else
                {
                    where.SearchCondition.Conditions.AddRange(search.Conditions);
                }
            }
        }
예제 #2
0
 void VisitX(SqlSearchCondition element)
 {
     foreach (var c in element.Conditions)
     {
         Visit(c);
     }
 }
예제 #3
0
 public SqlJoinedTable(JoinType joinType, SqlTableSource table, bool isWeak, SqlSearchCondition searchCondition)
 {
     JoinType        = joinType;
     Table           = table;
     IsWeak          = isWeak;
     Condition       = searchCondition;
     CanConvertApply = true;
 }
예제 #4
0
            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);
            }
예제 #5
0
        internal SqlMergeStatement(
            string?hint,
            SqlTableSource target,
            SqlTableLikeSource source,
            SqlSearchCondition on,
            IEnumerable <SqlMergeOperationClause> operations)
        {
            Hint   = hint;
            Target = target;
            Source = source;
            On     = on;

            foreach (var operation in operations)
            {
                Operations.Add(operation);
            }
        }
예제 #6
0
        IQueryElement?FindX(SqlSearchCondition sc)
        {
            if (sc.Conditions == null)
            {
                return(null);
            }

            foreach (var item in sc.Conditions)
            {
                var e = Find(item.Predicate);
                if (e != null)
                {
                    return(e);
                }
            }

            return(null);
        }
예제 #7
0
            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);
            }
예제 #8
0
        IQueryElement?ConvertInternal(IQueryElement?element)
        {
            if (element == null)
            {
                return(null);
            }

            // if element manually added outside to VisistedElements as null, it will be processed continuously.
            // Useful when we have to duplicate such items, especially parameters
            var newElement = GetCurrentReplaced(element);

            if (newElement != null)
            {
                return(newElement);
            }

            Stack.Add(element);
            try
            {
                switch (element.ElementType)
                {
                case QueryElementType.SqlFunction:
                {
                    var func  = (SqlFunction)element;
                    var parms = Convert(func.Parameters);

                    if (parms != null && !ReferenceEquals(parms, func.Parameters))
                    {
                        newElement = new SqlFunction(func.SystemType, func.Name, func.IsAggregate, func.Precedence, parms);
                    }

                    break;
                }

                case QueryElementType.SqlExpression:
                {
                    var expr      = (SqlExpression)element;
                    var parameter = Convert(expr.Parameters);

                    if (parameter != null && !ReferenceEquals(parameter, expr.Parameters))
                    {
                        newElement = new SqlExpression(expr.SystemType, expr.Expr, expr.Precedence, parameter);
                    }

                    break;
                }

                case QueryElementType.SqlBinaryExpression:
                {
                    var bexpr = (SqlBinaryExpression)element;
                    var expr1 = (ISqlExpression?)ConvertInternal(bexpr.Expr1);
                    var expr2 = (ISqlExpression?)ConvertInternal(bexpr.Expr2);

                    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 QueryElementType.SqlTable:
                {
                    var table    = (SqlTable)element;
                    var newTable = (SqlTable)_convert(this, table);

                    if (ReferenceEquals(newTable, table))
                    {
                        var targs = table.TableArguments == null || table.TableArguments.Length == 0 ?
                                    null : Convert(table.TableArguments);

                        if (targs != null && !ReferenceEquals(table.TableArguments, targs))
                        {
                            var newFields = table.Fields.Values.Select(f => new SqlField(f));
                            newTable = new SqlTable(table, newFields, targs);
                        }
                    }

                    if (!ReferenceEquals(table, newTable))
                    {
                        AddVisited(table.All, newTable.All);
                        foreach (var prevField in table.Fields.Values)
                        {
                            if (newTable.Fields.TryGetValue(prevField.Name, out var newField))
                            {
                                AddVisited(prevField, newField);
                            }
                        }
                    }

                    newElement = newTable;

                    break;
                }

                case QueryElementType.SqlCteTable:
                {
                    var table    = (SqlCteTable)element;
                    var newTable = (SqlCteTable)_convert(this, table);

                    if (ReferenceEquals(newTable, table))
                    {
                        var cte = (CteClause?)ConvertInternal(table.Cte);
                        var ce  = cte != null && !ReferenceEquals(table.Cte, cte);

                        if (ce)
                        {
                            var newFields = table.Fields.Values.Select(f => new SqlField(f));
                            newTable = new SqlCteTable(table, newFields, cte !);
                        }
                    }

                    if (!ReferenceEquals(table, newTable))
                    {
                        AddVisited(table.All, newTable.All);
                        foreach (var prevField in table.Fields.Values)
                        {
                            if (newTable.Fields.TryGetValue(prevField.Name, out var newField))
                            {
                                AddVisited(prevField, newField);
                            }
                        }
                    }

                    newElement = newTable;

                    break;
                }

                case QueryElementType.Column:
                {
                    var col  = (SqlColumn)element;
                    var expr = (ISqlExpression?)ConvertInternal(col.Expression);

                    if (expr != null && !ReferenceEquals(expr, col.Expression))
                    {
                        newElement = new SqlColumn(col.Parent, expr, col.RawAlias);
                    }

                    break;
                }

                case QueryElementType.TableSource:
                {
                    var table  = (SqlTableSource)element;
                    var source = (ISqlTableSource?)ConvertInternal(table.Source);
                    var joins  = Convert(table.Joins);

                    List <ISqlExpression[]>?uk = null;
                    if (table.HasUniqueKeys)
                    {
                        uk = ConvertListArray(table.UniqueKeys, null);
                    }

                    if (source != null && !ReferenceEquals(source, table.Source) ||
                        joins != null && !ReferenceEquals(table.Joins, joins))
                    {
                        newElement = new SqlTableSource(
                            source ?? table.Source,
                            table._alias,
                            joins ?? table.Joins,
                            uk ?? (table.HasUniqueKeys ? table.UniqueKeys : null));
                    }

                    break;
                }

                case QueryElementType.JoinedTable:
                {
                    var join  = (SqlJoinedTable)element;
                    var table = (SqlTableSource?)ConvertInternal(join.Table);
                    var cond  = (SqlSearchCondition?)ConvertInternal(join.Condition);

                    if (table != null && !ReferenceEquals(table, join.Table) ||
                        cond != null && !ReferenceEquals(cond, join.Condition))
                    {
                        newElement = new SqlJoinedTable(join.JoinType, table ?? join.Table, join.IsWeak, cond ?? join.Condition);
                    }

                    break;
                }

                case QueryElementType.SearchCondition:
                {
                    var sc    = (SqlSearchCondition)element;
                    var conds = Convert(sc.Conditions);

                    if (conds != null && !ReferenceEquals(sc.Conditions, conds))
                    {
                        newElement = new SqlSearchCondition(conds);
                    }

                    break;
                }

                case QueryElementType.Condition:
                {
                    var c = (SqlCondition)element;
                    var p = (ISqlPredicate?)ConvertInternal(c.Predicate);

                    if (p != null && !ReferenceEquals(c.Predicate, p))
                    {
                        newElement = new SqlCondition(c.IsNot, p, c.IsOr);
                    }

                    break;
                }

                case QueryElementType.ExprPredicate:
                {
                    var p = (SqlPredicate.Expr)element;
                    var e = (ISqlExpression?)ConvertInternal(p.Expr1);

                    if (e != null && !ReferenceEquals(p.Expr1, e))
                    {
                        newElement = new SqlPredicate.Expr(e, p.Precedence);
                    }

                    break;
                }

                case QueryElementType.NotExprPredicate:
                {
                    var p = (SqlPredicate.NotExpr)element;
                    var e = (ISqlExpression?)ConvertInternal(p.Expr1);

                    if (e != null && !ReferenceEquals(p.Expr1, e))
                    {
                        newElement = new SqlPredicate.NotExpr(e, p.IsNot, p.Precedence);
                    }

                    break;
                }

                case QueryElementType.ExprExprPredicate:
                {
                    var p  = (SqlPredicate.ExprExpr)element;
                    var e1 = (ISqlExpression?)ConvertInternal(p.Expr1);
                    var e2 = (ISqlExpression?)ConvertInternal(p.Expr2);

                    if (e1 != null && !ReferenceEquals(p.Expr1, e1) || e2 != null && !ReferenceEquals(p.Expr2, e2))
                    {
                        newElement = new SqlPredicate.ExprExpr(e1 ?? p.Expr1, p.Operator, e2 ?? p.Expr2);
                    }

                    break;
                }

                case QueryElementType.LikePredicate:
                {
                    var p  = (SqlPredicate.Like)element;
                    var e1 = (ISqlExpression?)ConvertInternal(p.Expr1);
                    var e2 = (ISqlExpression?)ConvertInternal(p.Expr2);
                    var es = (ISqlExpression?)ConvertInternal(p.Escape);

                    if (e1 != null && !ReferenceEquals(p.Expr1, e1) ||
                        e2 != null && !ReferenceEquals(p.Expr2, e2) ||
                        es != null && !ReferenceEquals(p.Escape, es))
                    {
                        newElement = new SqlPredicate.Like(e1 ?? p.Expr1, p.IsNot, e2 ?? p.Expr2, es ?? p.Escape, p.IsSqlLike);
                    }

                    break;
                }

                case QueryElementType.BetweenPredicate:
                {
                    var p  = (SqlPredicate.Between)element;
                    var e1 = (ISqlExpression?)ConvertInternal(p.Expr1);
                    var e2 = (ISqlExpression?)ConvertInternal(p.Expr2);
                    var e3 = (ISqlExpression?)ConvertInternal(p.Expr3);

                    if (e1 != null && !ReferenceEquals(p.Expr1, e1) ||
                        e2 != null && !ReferenceEquals(p.Expr2, e2) ||
                        e3 != null && !ReferenceEquals(p.Expr3, e3))
                    {
                        newElement = new SqlPredicate.Between(e1 ?? p.Expr1, p.IsNot, e2 ?? p.Expr2, e3 ?? p.Expr3);
                    }

                    break;
                }

                case QueryElementType.IsNullPredicate:
                {
                    var p = (SqlPredicate.IsNull)element;
                    var e = (ISqlExpression?)ConvertInternal(p.Expr1);

                    if (e != null && !ReferenceEquals(p.Expr1, e))
                    {
                        newElement = new SqlPredicate.IsNull(e, p.IsNot);
                    }

                    break;
                }

                case QueryElementType.InSubQueryPredicate:
                {
                    var p = (SqlPredicate.InSubQuery)element;
                    var e = (ISqlExpression?)ConvertInternal(p.Expr1);
                    var q = (SelectQuery?)ConvertInternal(p.SubQuery);

                    if (e != null && !ReferenceEquals(p.Expr1, e) || q != null && !ReferenceEquals(p.SubQuery, q))
                    {
                        newElement = new SqlPredicate.InSubQuery(e ?? p.Expr1, p.IsNot, q ?? p.SubQuery);
                    }

                    break;
                }

                case QueryElementType.InListPredicate:
                {
                    var p = (SqlPredicate.InList)element;
                    var e = (ISqlExpression?)ConvertInternal(p.Expr1);
                    var v = Convert(p.Values);

                    if (e != null && !ReferenceEquals(p.Expr1, e) || v != null && !ReferenceEquals(p.Values, v))
                    {
                        newElement = new SqlPredicate.InList(e ?? p.Expr1, p.IsNot, v ?? p.Values);
                    }

                    break;
                }

                case QueryElementType.FuncLikePredicate:
                {
                    var p = (SqlPredicate.FuncLike)element;
                    var f = (SqlFunction?)ConvertInternal(p.Function);

                    if (f != null && !ReferenceEquals(p.Function, f))
                    {
                        newElement = new SqlPredicate.FuncLike(f);
                    }

                    break;
                }

                case QueryElementType.SetExpression:
                {
                    var s = (SqlSetExpression)element;
                    var c = (ISqlExpression?)ConvertInternal(s.Column);
                    var e = (ISqlExpression?)ConvertInternal(s.Expression);

                    if (c != null && !ReferenceEquals(s.Column, c) || e != null && !ReferenceEquals(s.Expression, e))
                    {
                        newElement = new SqlSetExpression(c ?? s.Column, e ?? s.Expression !);
                    }

                    break;
                }

                case QueryElementType.InsertClause:
                {
                    var s = (SqlInsertClause)element;
                    var t = s.Into != null ? (SqlTable?)ConvertInternal(s.Into) : null;
                    var i = Convert(s.Items);

                    if (t != null && !ReferenceEquals(s.Into, t) || i != null && !ReferenceEquals(s.Items, i))
                    {
                        var sc = new SqlInsertClause {
                            Into = t ?? s.Into
                        };

                        sc.Items.AddRange(i ?? s.Items);
                        sc.WithIdentity = s.WithIdentity;

                        newElement = sc;
                    }

                    break;
                }

                case QueryElementType.UpdateClause:
                {
                    var s = (SqlUpdateClause)element;
                    var t = s.Table != null ? (SqlTable?)ConvertInternal(s.Table) : null;
                    var i = Convert(s.Items);
                    var k = Convert(s.Keys);

                    if (t != null && !ReferenceEquals(s.Table, t) ||
                        i != null && !ReferenceEquals(s.Items, i) ||
                        k != null && !ReferenceEquals(s.Keys, k))
                    {
                        var sc = new SqlUpdateClause {
                            Table = t ?? s.Table
                        };

                        sc.Items.AddRange(i ?? s.Items);
                        sc.Keys.AddRange(k ?? s.Keys);

                        newElement = sc;
                    }

                    break;
                }

                case QueryElementType.SelectStatement:
                {
                    var s           = (SqlSelectStatement)element;
                    var selectQuery = (SelectQuery?)ConvertInternal(s.SelectQuery);
                    var with        = s.With != null ? (SqlWithClause?)ConvertInternal(s.With) : null;
                    var ps          = ConvertSafe(s.Parameters);

                    if (ps != null && !ReferenceEquals(s.Parameters, ps) ||
                        selectQuery != null && !ReferenceEquals(s.SelectQuery, selectQuery) ||
                        with != null && !ReferenceEquals(s.With, with))
                    {
                        newElement = new SqlSelectStatement(selectQuery ?? s.SelectQuery);
                        ((SqlSelectStatement)newElement).Parameters.AddRange(ps ?? s.Parameters);
                        ((SqlSelectStatement)newElement).With = with ?? s.With;
                        CorrectQueryHierarchy(((SqlSelectStatement)newElement).SelectQuery);
                    }

                    break;
                }

                case QueryElementType.InsertStatement:
                {
                    var s           = (SqlInsertStatement)element;
                    var selectQuery = (SelectQuery?    )ConvertInternal(s.SelectQuery);
                    var insert      = (SqlInsertClause?)ConvertInternal(s.Insert);
                    var with        = s.With != null ? (SqlWithClause?)ConvertInternal(s.With) : null;
                    var ps          = ConvertSafe(s.Parameters);

                    if (insert != null && !ReferenceEquals(s.Insert, insert) ||
                        ps != null && !ReferenceEquals(s.Parameters, ps) ||
                        selectQuery != null && !ReferenceEquals(s.SelectQuery, selectQuery) ||
                        with != null && !ReferenceEquals(s.With, with))
                    {
                        newElement = new SqlInsertStatement(selectQuery ?? s.SelectQuery)
                        {
                            Insert = insert ?? s.Insert
                        };
                        ((SqlInsertStatement)newElement).Parameters.AddRange(ps ?? s.Parameters);
                        ((SqlInsertStatement)newElement).With = with ?? s.With;
                        CorrectQueryHierarchy(((SqlInsertStatement)newElement).SelectQuery);
                    }

                    break;
                }

                case QueryElementType.UpdateStatement:
                {
                    var s           = (SqlUpdateStatement)element;
                    var selectQuery = (SelectQuery?    )ConvertInternal(s.SelectQuery);
                    var update      = (SqlUpdateClause?)ConvertInternal(s.Update);
                    var with        = s.With != null ? (SqlWithClause?)ConvertInternal(s.With) : null;
                    var ps          = ConvertSafe(s.Parameters);

                    if (update != null && !ReferenceEquals(s.Update, update) ||
                        ps != null && !ReferenceEquals(s.Parameters, ps) ||
                        selectQuery != null && !ReferenceEquals(s.SelectQuery, selectQuery) ||
                        with != null && !ReferenceEquals(s.With, with))
                    {
                        newElement = new SqlUpdateStatement(selectQuery ?? s.SelectQuery)
                        {
                            Update = update ?? s.Update
                        };
                        ((SqlUpdateStatement)newElement).Parameters.AddRange(ps ?? s.Parameters);
                        ((SqlUpdateStatement)newElement).With = with ?? s.With;
                        CorrectQueryHierarchy(((SqlUpdateStatement)newElement).SelectQuery);
                    }

                    break;
                }

                case QueryElementType.InsertOrUpdateStatement:
                {
                    var s = (SqlInsertOrUpdateStatement)element;

                    var selectQuery = (SelectQuery?    )ConvertInternal(s.SelectQuery);
                    var insert      = (SqlInsertClause?)ConvertInternal(s.Insert);
                    var update      = (SqlUpdateClause?)ConvertInternal(s.Update);
                    var with        = s.With != null ? (SqlWithClause?)ConvertInternal(s.With) : null;
                    var ps          = ConvertSafe(s.Parameters);

                    if (insert != null && !ReferenceEquals(s.Insert, insert) ||
                        update != null && !ReferenceEquals(s.Update, update) ||
                        ps != null && !ReferenceEquals(s.Parameters, ps) ||
                        selectQuery != null && !ReferenceEquals(s.SelectQuery, selectQuery) ||
                        with != null && !ReferenceEquals(s.With, with))
                    {
                        newElement = new SqlInsertOrUpdateStatement(selectQuery ?? s.SelectQuery)
                        {
                            Insert = insert ?? s.Insert, Update = update ?? s.Update
                        };
                        ((SqlInsertOrUpdateStatement)newElement).Parameters.AddRange(ps ?? s.Parameters);
                        ((SqlInsertOrUpdateStatement)newElement).With = with ?? s.With;
                        CorrectQueryHierarchy(((SqlInsertOrUpdateStatement)newElement).SelectQuery);
                    }

                    break;
                }

                case QueryElementType.DeleteStatement:
                {
                    var s           = (SqlDeleteStatement)element;
                    var selectQuery = s.SelectQuery != null ? (SelectQuery?)ConvertInternal(s.SelectQuery) : null;
                    var table       = s.Table != null ? (SqlTable?)ConvertInternal(s.Table) : null;
                    var top         = s.Top != null ? (ISqlExpression?)ConvertInternal(s.Top) : null;
                    var with        = s.With != null ? (SqlWithClause?)ConvertInternal(s.With) : null;
                    var ps          = ConvertSafe(s.Parameters);

                    if (table != null && !ReferenceEquals(s.Table, table) ||
                        top != null && !ReferenceEquals(s.Top, top) ||
                        ps != null && !ReferenceEquals(s.Parameters, ps) ||
                        selectQuery != null && !ReferenceEquals(s.SelectQuery, selectQuery) ||
                        with != null && !ReferenceEquals(s.With, with))
                    {
                        newElement = new SqlDeleteStatement
                        {
                            Table                = table ?? s.Table,
                            SelectQuery          = selectQuery ?? s.SelectQuery,
                            Top                  = top ?? s.Top !,
                            IsParameterDependent = s.IsParameterDependent
                        };
                        ((SqlDeleteStatement)newElement).Parameters.AddRange(ps ?? s.Parameters);
                        ((SqlDeleteStatement)newElement).With = with ?? s.With;
                        CorrectQueryHierarchy(((SqlDeleteStatement)newElement).SelectQuery);
                    }

                    break;
                }

                case QueryElementType.CreateTableStatement:
                {
                    var s  = (SqlCreateTableStatement)element;
                    var t  = s.Table != null ? (SqlTable?)ConvertInternal(s.Table) : null;
                    var ps = ConvertSafe(s.Parameters);

                    if (t != null && !ReferenceEquals(s.Table, t) ||
                        ps != null && !ReferenceEquals(s.Parameters, ps))
                    {
                        newElement = new SqlCreateTableStatement {
                            Table = t ?? s.Table
                        };
                        if (ps != null)
                        {
                            ((SqlCreateTableStatement)newElement).Parameters.AddRange(ps);
                        }
                        else
                        {
                            ((SqlCreateTableStatement)newElement).Parameters.AddRange(s.Parameters);
                        }
                    }

                    break;
                }

                case QueryElementType.DropTableStatement:
                {
                    var s  = (SqlDropTableStatement)element;
                    var t  = s.Table != null ? (SqlTable?)ConvertInternal(s.Table) : null;
                    var ps = ConvertSafe(s.Parameters);

                    if (t != null && !ReferenceEquals(s.Table, t) ||
                        ps != null && !ReferenceEquals(s.Parameters, ps))
                    {
                        newElement = new SqlDropTableStatement(s.IfExists)
                        {
                            Table = t ?? s.Table
                        };
                        if (ps != null)
                        {
                            ((SqlDropTableStatement)newElement).Parameters.AddRange(ps);
                        }
                        else
                        {
                            ((SqlDropTableStatement)newElement).Parameters.AddRange(s.Parameters);
                        }
                    }

                    break;
                }

                case QueryElementType.SelectClause:
                {
                    var sc   = (SqlSelectClause)element;
                    var cols = Convert(sc.Columns, CloneColumn);
                    var take = (ISqlExpression?)ConvertInternal(sc.TakeValue);
                    var skip = (ISqlExpression?)ConvertInternal(sc.SkipValue);

                    if (
                        cols != null && !ReferenceEquals(sc.Columns, cols) ||
                        take != null && !ReferenceEquals(sc.TakeValue, take) ||
                        skip != null && !ReferenceEquals(sc.SkipValue, skip))
                    {
                        newElement = new SqlSelectClause(sc.IsDistinct, take ?? sc.TakeValue, sc.TakeHints, skip ?? sc.SkipValue, cols ?? sc.Columns);
                        ((SqlSelectClause)newElement).SetSqlQuery(sc.SelectQuery);
                    }
예제 #9
0
            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);
            }
예제 #10
0
 internal SqlWhereClause(SqlSearchCondition searchCondition) : base(null)
 {
     SearchCondition = searchCondition;
 }
예제 #11
0
 internal SqlWhereClause(SelectQuery selectQuery) : base(selectQuery)
 {
     SearchCondition = new SqlSearchCondition();
 }
예제 #12
0
 ISqlExpression?ISqlExpressionWalkable.Walk <TContext>(WalkOptions options, TContext context, Func <TContext, ISqlExpression, ISqlExpression> func)
 {
     SearchCondition = (SqlSearchCondition)((ISqlExpressionWalkable)SearchCondition).Walk(options, context, func) !;
     return(null);
 }
예제 #13
0
 ISqlExpression ISqlExpressionWalkable.Walk(bool skipColumns, Func <ISqlExpression, ISqlExpression> action)
 {
     SearchCondition = (SqlSearchCondition)((ISqlExpressionWalkable)SearchCondition).Walk(skipColumns, action);
     return(null);
 }
예제 #14
0
 ISqlExpression ISqlExpressionWalkable.Walk(WalkOptions options, Func <ISqlExpression, ISqlExpression> action)
 {
     SearchCondition = (SqlSearchCondition)((ISqlExpressionWalkable)SearchCondition).Walk(options, action);
     return(null);
 }
예제 #15
0
 internal Next(SqlSearchCondition parent)
 {
     _parent = parent;
 }
예제 #16
0
        static SqlPredicate ConvertInListPredicate(MappingSchema mappingSchema, SqlPredicate.InList p)
        {
            if (p.Values == null || p.Values.Count == 0)
            {
                return(new SqlPredicate.Expr(new SqlValue(p.IsNot)));
            }

            if (p.Values.Count == 1 && p.Values[0] is SqlParameter)
            {
                var pr = (SqlParameter)p.Values[0];

                if (pr.Value == null)
                {
                    return(new SqlPredicate.Expr(new SqlValue(p.IsNot)));
                }

                if (pr.Value is IEnumerable)
                {
                    var items = (IEnumerable)pr.Value;

                    if (p.Expr1 is ISqlTableSource)
                    {
                        var table = (ISqlTableSource)p.Expr1;
                        var keys  = table.GetKeys(true);

                        if (keys == null || keys.Count == 0)
                        {
                            throw new SqlException("Cant create IN expression.");
                        }

                        if (keys.Count == 1)
                        {
                            var values = new List <ISqlExpression>();
                            var field  = GetUnderlyingField(keys[0]);
                            var cd     = field.ColumnDescriptor;

                            foreach (var item in items)
                            {
                                var value = cd.MemberAccessor.GetValue(item);
                                values.Add(mappingSchema.GetSqlValue(cd.MemberType, value));
                            }

                            if (values.Count == 0)
                            {
                                return(new SqlPredicate.Expr(new SqlValue(p.IsNot)));
                            }

                            return(new SqlPredicate.InList(keys[0], p.IsNot, values));
                        }

                        {
                            var sc = new SqlSearchCondition();

                            foreach (var item in items)
                            {
                                var itemCond = new SqlSearchCondition();

                                foreach (var key in keys)
                                {
                                    var field = GetUnderlyingField(key);
                                    var cd    = field.ColumnDescriptor;
                                    var value = cd.MemberAccessor.GetValue(item);
                                    var cond  = value == null ?
                                                new SqlCondition(false, new SqlPredicate.IsNull(field, false)) :
                                                new SqlCondition(false, new SqlPredicate.ExprExpr(field, SqlPredicate.Operator.Equal, mappingSchema.GetSqlValue(value)));

                                    itemCond.Conditions.Add(cond);
                                }

                                sc.Conditions.Add(new SqlCondition(false, new SqlPredicate.Expr(itemCond), true));
                            }

                            if (sc.Conditions.Count == 0)
                            {
                                return(new SqlPredicate.Expr(new SqlValue(p.IsNot)));
                            }

                            if (p.IsNot)
                            {
                                return(new SqlPredicate.NotExpr(sc, true, SqlQuery.Precedence.LogicalNegation));
                            }

                            return(new SqlPredicate.Expr(sc, SqlQuery.Precedence.LogicalDisjunction));
                        }
                    }

                    if (p.Expr1 is ObjectSqlExpression)
                    {
                        var expr = (ObjectSqlExpression)p.Expr1;

                        if (expr.Parameters.Length == 1)
                        {
                            var values = new List <ISqlExpression>();

                            foreach (var item in items)
                            {
                                var value = expr.GetValue(item, 0);
                                values.Add(new SqlValue(value));
                            }

                            if (values.Count == 0)
                            {
                                return(new SqlPredicate.Expr(new SqlValue(p.IsNot)));
                            }

                            return(new SqlPredicate.InList(expr.Parameters[0], p.IsNot, values));
                        }

                        var sc = new SqlSearchCondition();

                        foreach (var item in items)
                        {
                            var itemCond = new SqlSearchCondition();

                            for (var i = 0; i < expr.Parameters.Length; i++)
                            {
                                var sql   = expr.Parameters[i];
                                var value = expr.GetValue(item, i);
                                var cond  = value == null ?
                                            new SqlCondition(false, new SqlPredicate.IsNull(sql, false)) :
                                            new SqlCondition(false, new SqlPredicate.ExprExpr(sql, SqlPredicate.Operator.Equal, new SqlValue(value)));

                                itemCond.Conditions.Add(cond);
                            }

                            sc.Conditions.Add(new SqlCondition(false, new SqlPredicate.Expr(itemCond), true));
                        }

                        if (sc.Conditions.Count == 0)
                        {
                            return(new SqlPredicate.Expr(new SqlValue(p.IsNot)));
                        }

                        if (p.IsNot)
                        {
                            return(new SqlPredicate.NotExpr(sc, true, SqlQuery.Precedence.LogicalNegation));
                        }

                        return(new SqlPredicate.Expr(sc, SqlQuery.Precedence.LogicalDisjunction));
                    }
                }
            }

            return(null);
        }
예제 #17
0
 ISqlExpression?ISqlExpressionWalkable.Walk(WalkOptions options, Func <ISqlExpression, ISqlExpression> func)
 {
     SearchCondition = (SqlSearchCondition)((ISqlExpressionWalkable)SearchCondition).Walk(options, func) !;
     return(null);
 }