Ejemplo n.º 1
0
        /// <summary>
        ///     Creates a <see cref="ICriterion" /> for a binary operation.
        /// </summary>
        /// <param name="a">
        ///     Expression A.
        /// </param>
        /// <param name="b">
        ///     Expression B.
        /// </param>
        /// <param name="type">
        ///     The operation type.
        /// </param>
        /// <param name="context">
        ///     The helper context.
        /// </param>
        /// <returns>
        ///     The created <see cref="ICriterion" />.
        /// </returns>
        public static ICriterion GetCriterionForBinary
        (
            Expression a,
            Expression b,
            ExpressionType type,
            HelperContext context
        )
        {
            if (a.NodeType == ExpressionType.Convert)
            {
                return(GetCriterionForBinary(((UnaryExpression)a).Operand, b, type, context));
            }

            if (b.NodeType == ExpressionType.Convert)
            {
                return(GetCriterionForBinary(a, ((UnaryExpression)b).Operand, type, context));
            }

            switch (type)
            {
            case ExpressionType.AndAlso:
                return(Restrictions.And(GetCriterion(a, context), GetCriterion(b, context)));

            case ExpressionType.OrElse:
                return(Restrictions.Or(GetCriterion(a, context), GetCriterion(b, context)));

            case ExpressionType.ExclusiveOr:

                ICriterion criterionA = GetCriterion(a, context);
                ICriterion criterionB = GetCriterion(b, context);

                return(Restrictions
                       .Or
                       (
                           Restrictions.And(criterionA, Restrictions.Not(criterionB)),
                           Restrictions.And(criterionB, Restrictions.Not(criterionA))
                       ));
            }

            bool isProjectedA = IsProjected(a, context);
            bool isProjectedB = IsProjected(b, context);

            // Projection-Projection
            if (isProjectedA && isProjectedB)
            {
                return(GetProjectionProjectionCriterion
                       (
                           ProjectionHelper.GetProjection(a, context),
                           ProjectionHelper.GetProjection(b, context),
                           type
                       ));
            }

            if (isProjectedA || !isProjectedB)
            {
                return(GetProjectionValueCriterion(a, ExpressionHelper.GetValue(b), type, context, false));
            }

            return(GetProjectionValueCriterion(b, ExpressionHelper.GetValue(a), type, context, true));
        }
Ejemplo n.º 2
0
        /// <summary>
        ///     Generates new orders based on the underlying source by resolving the appropriate projections from the
        ///     given lambda expression.
        /// </summary>
        /// <param name="orderByStatements">
        ///     The order by statements.
        /// </param>
        /// <param name="projection">
        ///     The projection.
        /// </param>
        /// <param name="data">
        ///     The helper data.
        /// </param>
        /// <returns>
        ///     The new set of orders.
        /// </returns>
        /// <exception cref="ArgumentNullException">
        ///     <paramref name="orderByStatements" />, <paramref name="projection" /> or <paramref name="data" /> is
        ///     null.
        /// </exception>
        public static IEnumerable <OrderByStatement> GetSourceBasedOrdersFrom
        (
            IEnumerable <OrderByStatement> orderByStatements,
            LambdaExpression projection,
            QueryHelperData data
        )
        {
            if (orderByStatements == null)
            {
                throw new ArgumentNullException("orderByStatements");
            }

            if (projection == null)
            {
                throw new ArgumentNullException("projection");
            }

            if (data == null)
            {
                throw new ArgumentNullException("data");
            }

            if (orderByStatements.All(x => x.IsBasedOnSource))
            {
                return(orderByStatements);
            }

            ProjectionHelper.GetProjection(projection, new HelperContext(data, projection, HelperType.Select));

            var orders = new List <OrderByStatement>();

            foreach (var statement in orderByStatements)
            {
                if (statement.IsBasedOnSource)
                {
                    orders.Add(statement);

                    continue;
                }

                IProjection orderProjection;

                bool foundMapping = data.Mappings
                                    .TryGetValue(statement.Property, out orderProjection);

                if (foundMapping)
                {
                    var order = new OrderByStatement
                    {
                        IsBasedOnSource = true,
                        Order           = new Order(orderProjection, statement.OrderAscending)
                    };

                    orders.Add(order);
                }
            }

            return(orders);
        }
Ejemplo n.º 3
0
        /// <summary>
        ///     Creates <see cref="ICriterion" /> for a comparison between a value and a projection.
        /// </summary>
        /// <param name="expression">
        ///     The expression.
        /// </param>
        /// <param name="value">
        ///     The value.
        /// </param>
        /// <param name="type">
        ///     The comparison type.
        /// </param>
        /// <param name="context">
        ///     The helper context.
        /// </param>
        /// <param name="overTurned">
        ///     Indicates whether the comparison has been reversed to simplify other code.
        /// </param>
        /// <returns>
        ///     The created <see cref="ICriterion" />.
        /// </returns>
        /// <exception cref="NotSupportedException">
        ///     The <see cref="Expression" /> could not be resolved as it may contain unsupported features or similar.
        /// </exception>
        public static ICriterion GetProjectionValueCriterion
        (
            Expression expression,
            object value,
            ExpressionType type,
            HelperContext context,
            bool overTurned
        )
        {
            if (overTurned)
            {
                switch (type)
                {
                case ExpressionType.GreaterThan:
                    type = ExpressionType.LessThan;
                    break;

                case ExpressionType.GreaterThanOrEqual:
                    type = ExpressionType.LessThanOrEqual;
                    break;

                case ExpressionType.LessThan:
                    type = ExpressionType.GreaterThan;
                    break;

                case ExpressionType.LessThanOrEqual:
                    type = ExpressionType.GreaterThanOrEqual;
                    break;
                }
            }

            IProjection projection = ProjectionHelper.GetProjection(expression, context);

            switch (type)
            {
            case ExpressionType.Equal:

                if (value == null)
                {
                    return(Restrictions.IsNull(projection));
                }

                if (value is bool)
                {
                    return(GetCriterion((bool)value ? expression : Expression.Not(expression), context));
                }

                return(Restrictions.Eq(projection, value));

            case ExpressionType.NotEqual:

                if (value == null)
                {
                    return(Restrictions.IsNotNull(projection));
                }

                if (value is bool)
                {
                    return(GetCriterion(!(bool)value ? expression : Expression.Not(expression), context));
                }

                return(Restrictions.Not(Restrictions.Eq(projection, value)));

            case ExpressionType.GreaterThan:
                return(Restrictions.Gt(projection, value));

            case ExpressionType.GreaterThanOrEqual:
                return(Restrictions.Ge(projection, value));

            case ExpressionType.LessThan:
                return(Restrictions.Lt(projection, value));

            case ExpressionType.LessThanOrEqual:
                return(Restrictions.Le(projection, value));

            default:
                throw new NotSupportedException
                      (
                          "the expression contains unsupported features, please revise your code"
                      );
            }
        }
Ejemplo n.º 4
0
        /// <summary>
        ///     Creates a <see cref="ICriterion" /> for the given <see cref="MethodCallExpression" />.
        /// </summary>
        /// <param name="expression">
        ///     The expression.
        /// </param>
        /// <param name="context">
        ///     The helper context.
        /// </param>
        /// <returns>
        ///     The created <see cref="ICriterion" />.
        /// </returns>
        public static ICriterion GetCriterionForMethodCall
        (
            MethodCallExpression expression,
            HelperContext context
        )
        {
            if (IsProjected(expression, context))
            {
                // Not a value expression
                IProjection projection = ProjectionHelper
                                         .GetProjection
                                         (
                    expression.Object ?? expression.Arguments[0],
                    context
                                         );

                int i = expression.Object == null ? 1 : 0;

                switch (expression.Method.Name)
                {
                case "In":
                case "IsIn":

                    object value = ExpressionHelper.GetValue(expression.Arguments[i]);

                    if (!(value is ICollection))
                    {
                        if (value is IEnumerable)
                        {
                            var objs = new List <object>();

                            foreach (object obj in value as IEnumerable)
                            {
                                objs.Add(obj);
                            }

                            return(Restrictions
                                   .In
                                   (
                                       projection,
                                       objs.ToArray()
                                   ));
                        }

                        if (value is IDetachedImmutableFlowQuery)
                        {
                            return(Subqueries
                                   .PropertyIn
                                   (
                                       ExpressionHelper.GetPropertyName(expression, context.RootAlias),
                                       (value as IDetachedImmutableFlowQuery).Criteria
                                   ));
                        }
                    }

                    return(Restrictions
                           .In
                           (
                               projection,
                               value as ICollection
                           ));

                case "Between":
                case "IsBetween":
                    return(Restrictions
                           .Between
                           (
                               projection,
                               ExpressionHelper.GetValue(expression.Arguments[i]),
                               ExpressionHelper.GetValue(expression.Arguments[i + 1])
                           ));

                case "Like":
                case "IsLike":
                    return(GetLikeCriterion(projection, expression.Arguments[i], MatchMode.Exact));

                case "StartsWith":
                    return(GetLikeCriterion(projection, expression.Arguments[i], MatchMode.Start));

                case "EndsWith":
                    return(GetLikeCriterion(projection, expression.Arguments[i], MatchMode.End));

                case "Contains":
                    return(GetLikeCriterion(projection, expression.Arguments[i], MatchMode.Anywhere));

                case "IsLessThan":
                    return(Restrictions.Lt(projection, ExpressionHelper.GetValue(expression.Arguments[i])));

                case "IsLessThanOrEqualTo":
                    return(Restrictions.Le(projection, ExpressionHelper.GetValue(expression.Arguments[i])));

                case "IsGreaterThan":
                    return(Restrictions.Gt(projection, ExpressionHelper.GetValue(expression.Arguments[i])));

                case "IsGreaterThanOrEqualTo":
                    return(Restrictions.Ge(projection, ExpressionHelper.GetValue(expression.Arguments[i])));

                case "IsEqualTo":
                    return(Restrictions.Eq(projection, ExpressionHelper.GetValue(expression.Arguments[i])));

                case "IsNull":
                    return(Restrictions.IsNull(projection));

                case "IsNotNull":
                    return(Restrictions.IsNotNull(projection));
                }

                throw new NotSupportedException
                      (
                          "The expression contains unsupported features, please revise your code"
                      );
            }

            return(Restrictions.Eq(Projections.Constant(ExpressionHelper.GetValue <bool>(expression)), true));
        }