예제 #1
0
        internal static IQueryable GetSubGroupsAndCountsQueryable(this IQueryable queryable, string subGroupBy, bool sortGroupBy, ListSortDirection direction)
        {
            // Create GroupBy
            Type queryableElementType = queryable.ElementType;

            ParameterExpression[] parameters              = new ParameterExpression[] { Expression.Parameter(queryableElementType, "") };
            MemberExpression      memberExpression        = QueryableExtensions.GenerateMemberExpression(parameters[0], subGroupBy);
            LambdaExpression      groupByLambdaExpression = Expression.Lambda(memberExpression, parameters);

            MethodCallExpression groupByMethodExpression =
                Expression.Call(
                    typeof(Queryable), "GroupBy",
                    new Type[] { queryableElementType, groupByLambdaExpression.Body.Type },
                    new Expression[] { queryable.Expression, Expression.Quote(groupByLambdaExpression) });

            IQueryable groupedResult = queryable.Provider.CreateQuery(groupByMethodExpression);

            if (sortGroupBy)
            {
                groupedResult = groupedResult.OrderByKey(direction == ListSortDirection.Ascending);
            }

            ParameterExpression[] groupedParameters = new ParameterExpression[] { System.Linq.Expressions.Expression.Parameter(groupedResult.ElementType, "") };

            MemberExpression     keyMemberExpression = MemberExpression.Property(groupedParameters[0], "Key");
            MethodCallExpression countCallExpression = MethodCallExpression.Call(typeof(Enumerable), "Count", new Type[] { queryableElementType }, groupedParameters);

            QueryableGroupNameCountPairInfo queryableGroupNameCountPairInfo =
                QueryableExtensions.QueryableGroupNameCountPairInfos.GetInfosForType(memberExpression.Type);

            Expression[] newExpressionArguments = new Expression[2] {
                keyMemberExpression, countCallExpression
            };

            NewExpression newExpression =
                NewExpression.New(
                    queryableGroupNameCountPairInfo.ConstructorInfo,
                    newExpressionArguments,
                    new MemberInfo[] { queryableGroupNameCountPairInfo.KeyPropertyInfo, queryableGroupNameCountPairInfo.CountPropertyInfo });

            LambdaExpression finalLambdaExpression = System.Linq.Expressions.Expression.Lambda(newExpression, groupedParameters);

            MethodCallExpression finalSelectExpression =
                System.Linq.Expressions.Expression.Call(
                    typeof(Queryable), "Select",
                    new Type[] { groupedResult.ElementType, finalLambdaExpression.Body.Type },
                    new System.Linq.Expressions.Expression[] { groupedResult.Expression, System.Linq.Expressions.Expression.Quote(finalLambdaExpression) });

            return(groupedResult.Provider.CreateQuery(finalSelectExpression));
        }
예제 #2
0
        public void MakeSerializable_SerializableType_WithInitializations()
        {
            StubFilterWithNoSerializedFields();
            var initMethod = CreateInitializationMethod(_serializableProxy);

            _enabler.MakeSerializable(_serializableProxy, initMethod);

            Assert.That(_serializableProxy.AddedInterfaces, Is.EqualTo(new[] { typeof(IDeserializationCallback) }));
            Assert.That(_serializableProxy.AddedMethods, Has.Count.EqualTo(1));

            var method = _serializableProxy.AddedMethods.Single();

            Assert.That(method.Name, Is.EqualTo("System.Runtime.Serialization.IDeserializationCallback.OnDeserialization"));
            Assert.That(method.GetParameters().Select(p => p.ParameterType), Is.EqualTo(new[] { typeof(object) }));
            var expectedBody = MethodCallExpression.Call(
                new ThisExpression(_serializableProxy), initMethod, Expression.Constant(InitializationSemantics.Deserialization));

            ExpressionTreeComparer.CheckAreEqualTrees(expectedBody, method.Body);
        }
예제 #3
0
        private Expression GetExpressionForNodeType(
            BinaryExpression expression, MethodCallExpression leftSideAsMethodCallExpression, ConstantExpression leftSideArgument2AsConstantExpression)
        {
            BinaryExpression binaryExpression;

            switch (expression.NodeType)
            {
            case ExpressionType.Equal:
                binaryExpression = Expression.Equal(leftSideAsMethodCallExpression.Arguments[0], leftSideAsMethodCallExpression.Arguments[1]);
                return(new VBStringComparisonExpression(binaryExpression, (bool)leftSideArgument2AsConstantExpression.Value));

            case ExpressionType.NotEqual:
                binaryExpression = Expression.NotEqual(leftSideAsMethodCallExpression.Arguments[0], leftSideAsMethodCallExpression.Arguments[1]);
                return(new VBStringComparisonExpression(binaryExpression, (bool)leftSideArgument2AsConstantExpression.Value));
            }

            var methodCallExpression = MethodCallExpression.Call(
                leftSideAsMethodCallExpression.Arguments[0],
                s_stringCompareToMethod,
                new[] { leftSideAsMethodCallExpression.Arguments[1] });
            var vbExpression = new VBStringComparisonExpression(methodCallExpression, (bool)leftSideArgument2AsConstantExpression.Value);

            if (expression.NodeType == ExpressionType.GreaterThan)
            {
                return(Expression.GreaterThan(vbExpression, Expression.Constant(0)));
            }
            else if (expression.NodeType == ExpressionType.GreaterThanOrEqual)
            {
                return(Expression.GreaterThanOrEqual(vbExpression, Expression.Constant(0)));
            }
            else if (expression.NodeType == ExpressionType.LessThan)
            {
                return(Expression.LessThan(vbExpression, Expression.Constant(0)));
            }
            else if (expression.NodeType == ExpressionType.LessThanOrEqual)
            {
                return(Expression.LessThanOrEqual(vbExpression, Expression.Constant(0)));
            }

            throw new NotSupportedException(
                      string.Format("Binary expression with node type '{0}' is not supported in a VB string comparison.", expression.NodeType));
        }
        /// <summary>
        /// Checks if the binary expression is a string comparison emitted by the Visual Basic compiler.
        /// </summary>
        /// <remarks>The VB compiler translates string comparisons such as
        /// <code>(Function(x) x.Name = "a string value")</code> not as a binary expression with the field
        /// on the left side and the string value on the right side. Instead, it converts it into a call
        /// to <code>Microsoft.VisualBasic.CompilerServices.Operators.CompareString</code> (or
        /// <code>Microsoft.VisualBasic.CompilerServices.EmbeddedOperators</code> for phone platforms)
        /// for the string value, and compares the expression to zero.</remarks>
        /// <param name="expression">The binary expression to check.</param>
        /// <param name="stringComparison">A normalized string comparison expression.</param>
        /// <returns>True if the expression is a string comparison expression emitted by the VB compiler,
        /// otherwise false</returns>
        private bool CheckVBStringCompareExpression(BinaryExpression expression, out BinaryExpression stringComparison)
        {
            stringComparison = null;
            if (expression.Left.Type == typeofInt &&
                expression.Left.NodeType == ExpressionType.Call &&
                expression.Right.Type == typeofInt &&
                expression.Right.NodeType == ExpressionType.Constant &&
                ((ConstantExpression)expression.Right).Value.Equals(0))
            {
                MethodCallExpression methodCall = (MethodCallExpression)expression.Left;
                if ((methodCall.Method.DeclaringType.FullName == VBOperatorClass || methodCall.Method.DeclaringType.FullName == VBOperatorClassAlt) &&
                    methodCall.Method.Name == VBCompareStringMethod &&
                    methodCall.Arguments.Count == VBCompareStringArguments &&
                    methodCall.Arguments[VBCaseSensitiveCompareArgumentIndex].Type == typeof(bool) &&
                    methodCall.Arguments[VBCaseSensitiveCompareArgumentIndex].NodeType == ExpressionType.Constant)
                {
                    bool       doCaseInsensitiveComparison = ((ConstantExpression)methodCall.Arguments[VBCaseSensitiveCompareArgumentIndex]).Value.Equals(true);
                    Expression leftExpression  = methodCall.Arguments[0];
                    Expression rightExpression = methodCall.Arguments[1];
                    if (doCaseInsensitiveComparison)
                    {
                        leftExpression  = MethodCallExpression.Call(leftExpression, stringToLowerMethod);
                        rightExpression = MethodCallExpression.Call(rightExpression, stringToLowerMethod);
                    }

                    switch (expression.NodeType)
                    {
                    case ExpressionType.Equal:
                        stringComparison = BinaryExpression.Equal(leftExpression, rightExpression);
                        break;

                    case ExpressionType.NotEqual:
                        stringComparison = BinaryExpression.NotEqual(leftExpression, rightExpression);
                        break;

                    case ExpressionType.LessThan:
                        stringComparison = BinaryExpression.LessThan(leftExpression, rightExpression);
                        break;

                    case ExpressionType.LessThanOrEqual:
                        stringComparison = BinaryExpression.LessThanOrEqual(leftExpression, rightExpression);
                        break;

                    case ExpressionType.GreaterThan:
                        stringComparison = BinaryExpression.GreaterThan(leftExpression, rightExpression);
                        break;

                    case ExpressionType.GreaterThanOrEqual:
                        stringComparison = BinaryExpression.GreaterThanOrEqual(leftExpression, rightExpression);
                        break;
                    }

                    if (stringComparison != null)
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }