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)); }
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); }
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); }