예제 #1
0
        public override void Visit(SqlBinary node)
        {
            switch (node.NodeType)
            {
            // Bit XOR is not supported by SQLite
            // but it can be easily emulated using remaining bit operators
            case SqlNodeType.BitXor:
                // A ^ B = (A | B) & ~(A & B)
                var replacement = SqlDml.BitAnd(
                    SqlDml.BitOr(node.Left, node.Right),
                    SqlDml.BitNot(SqlDml.BitAnd(node.Left, node.Right)));
                replacement.AcceptVisitor(this);
                return;

            case SqlNodeType.DateTimePlusInterval:
                DateTimeAddInterval(node.Left, node.Right).AcceptVisitor(this);
                return;

            case SqlNodeType.DateTimeMinusInterval:
                DateTimeAddInterval(node.Left, -node.Right).AcceptVisitor(this);
                return;

            case SqlNodeType.DateTimeMinusDateTime:
            case SqlNodeType.DateTimeOffsetMinusDateTimeOffset:
                DateTimeSubtractDateTime(node.Left, node.Right).AcceptVisitor(this);
                return;

            case SqlNodeType.DateTimeOffsetPlusInterval:
                SqlDml.Concat(
                    DateTimeAddInterval(DateTimeOffsetExtractDateTimeAsString(node.Left), node.Right),
                    DateTimeOffsetExtractOffsetAsString(node.Left))
                .AcceptVisitor(this);
                return;

            case SqlNodeType.DateTimeOffsetMinusInterval:
                SqlDml.Concat(
                    DateTimeAddInterval(DateTimeOffsetExtractDateTimeAsString(node.Left), -node.Right),
                    DateTimeOffsetExtractOffsetAsString(node.Left))
                .AcceptVisitor(this);
                return;

            default:
                base.Visit(node);
                return;
            }
        }
        protected override SqlExpression VisitUnary(UnaryExpression expression)
        {
            var operand = Visit(expression.Operand);

            if (expression.Method != null)
            {
                return(CompileMember(expression.Method, null, operand));
            }

            switch (expression.NodeType)
            {
            case ExpressionType.ArrayLength:
                if (expression.Operand.Type != typeof(byte[]))
                {
                    throw new NotSupportedException(string.Format(Strings.ExTypeXIsNotSupported, expression.Operand.Type));
                }
                return(SqlDml.Cast(SqlDml.BinaryLength(operand), driver.MapValueType(typeof(int))));

            case ExpressionType.Negate:
            case ExpressionType.NegateChecked:
                return(SqlDml.Negate(operand));

            case ExpressionType.UnaryPlus:
                return(operand);

            case ExpressionType.Not:
                return(IsBooleanExpression(expression.Operand)
            ? SqlDml.Not(operand)
            : SqlDml.BitNot(operand));

            case ExpressionType.Convert:
            case ExpressionType.ConvertChecked:
                return(VisitCast(expression, operand));
            }
            return(operand);
        }