예제 #1
0
        /// <summary>
        /// Extract a part of expression or sub-expression
        /// </summary>
        /// <typeparam name="T">The type of the expression which belong to</typeparam>
        /// <param name="binaryExpression">The binary expression which will resolve</param>
        /// <returns></returns>
        private static List <WhereExpressionResult> Extract <T>(BinaryExpression binaryExpression)
        {
            List <WhereExpressionResult> expressionResults = new List <WhereExpressionResult>();

            WhereExpressionResult expressionResult = new WhereExpressionResult();

            if (
                binaryExpression.NodeType == ExpressionType.Equal
                ||
                binaryExpression.NodeType == ExpressionType.NotEqual
                ||
                binaryExpression.NodeType == ExpressionType.LessThan
                ||
                binaryExpression.NodeType == ExpressionType.GreaterThan
                ||
                binaryExpression.NodeType == ExpressionType.LessThanOrEqual
                ||
                binaryExpression.NodeType == ExpressionType.GreaterThanOrEqual)
            {
                if (binaryExpression.Left is MemberExpression)
                {
                    MemberExpression memberExpression = binaryExpression.Left as MemberExpression;

                    if (memberExpression.Expression != null && memberExpression.Expression.Type == typeof(T))
                    {
                        expressionResult.MemberName = memberExpression.Member.Name;                                               // Name
                    }
                    else
                    {
                        expressionResult.MemberName  = (memberExpression.Expression as MemberExpression).Member.Name; // Name
                        expressionResult.SubProperty = memberExpression.Member.Name;                                  // Name.Length (Name.Length == 3)
                    }
                    expressionResult.Condition = binaryExpression.NodeType;                                           // ==
                    expressionResult.Value     = (binaryExpression.Right as ConstantExpression).Value.ToString();     // Foo
                    expressionResult.SubPropertyArgumentType = binaryExpression.Right.Type;
                    expressionResults.Add(expressionResult);
                }
                else if (binaryExpression.Left is MethodCallExpression)
                {
                    MethodCallExpression methodCallExpression = binaryExpression.Left as MethodCallExpression;
                    expressionResult.MemberName = (methodCallExpression.Object as MemberExpression).Member.Name;    //Name

                    expressionResult.SubProperty = methodCallExpression.Method.Name;                                // ToLower
                    if (methodCallExpression.Arguments != null && methodCallExpression.Arguments.Any())
                    {
                        expressionResult.SubPropertyArguments.AddRange(methodCallExpression.Arguments.Select(x => (x as ConstantExpression).Value).ToList());
                    }
                    expressionResult.Condition = binaryExpression.NodeType;                                       // ==
                    expressionResult.Value     = (binaryExpression.Right as ConstantExpression).Value.ToString(); // Foo
                    expressionResult.SubPropertyArgumentType = binaryExpression.Right.Type;
                    expressionResults.Add(expressionResult);
                }
            }
            else if (binaryExpression.NodeType == ExpressionType.OrElse)
            {
                expressionResults.Add(new WhereExpressionResult()
                {
                    Parentheses = "("
                });                                                                                               // (
                GetWhereExpressions <T>(binaryExpression.Left as BinaryExpression, expressionResults);            // Name == Goo
                expressionResults.Add(new WhereExpressionResult()
                {
                    Condition = ExpressionType.Or
                });                                                                                               // Or
                GetWhereExpressions <T>(binaryExpression.Right as BinaryExpression, expressionResults);           // Year == 2020
                expressionResults.Add(new WhereExpressionResult()
                {
                    Parentheses = ")"
                });                                                                                               // )
            }
            else if (binaryExpression.NodeType == ExpressionType.AndAlso)
            {
                expressionResults.Add(new WhereExpressionResult()
                {
                    Parentheses = "("
                });                                                                                               // (
                GetWhereExpressions <T>(binaryExpression.Left as BinaryExpression, expressionResults);            // (Name == Foo Or || Name == Goo)
                expressionResults.Add(new WhereExpressionResult()
                {
                    Condition = ExpressionType.And
                });                                                                                               // And
                GetWhereExpressions <T>(binaryExpression.Right as BinaryExpression, expressionResults);           // Year == 2020
                expressionResults.Add(new WhereExpressionResult()
                {
                    Parentheses = ")"
                });                                                                                               // )
            }

            return(expressionResults);
        }
예제 #2
0
        /// <summary>
        /// Extract a part of expression or sub-expression
        /// </summary>
        /// <typeparam name="T">The type of the expression which belong to</typeparam>
        /// <param name="methodCallExpression">The call of method expression which will resolve</param>
        /// <returns></returns>
        private static List <WhereExpressionResult> Extract <T>(MethodCallExpression methodCallExpression)
        {
            List <WhereExpressionResult> expressionResults = new List <WhereExpressionResult>();

            if (methodCallExpression.NodeType == ExpressionType.Call && methodCallExpression.Object is MemberExpression) //x.Name.StartsWith(F) or stringListItems.Contains(x.Name)
            {
                WhereExpressionResult expressionResult = new WhereExpressionResult();
                expressionResult.SubProperty = methodCallExpression.Method.Name;

                if (methodCallExpression.Object is MemberExpression)
                {
                    expressionResult.MemberName = (methodCallExpression.Object as MemberExpression).Member.Name; // x.Name.StartsWith(F) => "Name" or stringListItems.Contains(x.Name) => stringListItems
                }
                if (methodCallExpression.Arguments.FirstOrDefault() is MemberExpression)
                {
                    expressionResult.MemberName = (methodCallExpression.Arguments.FirstOrDefault() as MemberExpression).Member.Name; // stringListItems.Contains(x.Name) => "Name"
                }

                MemberExpression memberExpression = methodCallExpression.Object as MemberExpression;

                Expression subExpression = memberExpression.Expression;
                string     expressionParameterKeyword = memberExpression.Member.Name;

                if (subExpression is ConstantExpression) //stringListItems.Contains(x.Name)
                {
                    object subExpressionValue = (subExpression as ConstantExpression).Value;

                    if (methodCallExpression.Object.Type == typeof(List <string>))
                    {
                        List <string> values = subExpressionValue.GetType().GetField(expressionParameterKeyword).GetValue(subExpressionValue) as List <string>;
                        expressionResult.SubPropertyArgumentType = typeof(string);
                        expressionResult.SubPropertyArguments.AddRange(values); // stringListItems.Contains(x.Name) => elements of "stringListItems"
                    }
                    else if (methodCallExpression.Object.Type == typeof(List <int>))
                    {
                        List <int> values = subExpressionValue.GetType().GetField(expressionParameterKeyword).GetValue(subExpressionValue) as List <int>;
                        expressionResult.SubPropertyArgumentType = typeof(int);
                        expressionResult.SubPropertyArguments.AddRange(values.Select(x => x.ToString()).ToList());
                    }
                }
                else // x.Name.StartsWith(F)
                {
                    if (methodCallExpression.Arguments.FirstOrDefault() is ConstantExpression)
                    {
                        ConstantExpression constantExpression = methodCallExpression.Arguments.FirstOrDefault() as ConstantExpression;

                        expressionResult.SubPropertyArgumentType = constantExpression.Value.GetType();
                        expressionResult.Value = constantExpression.Value.ToString(); // x.Name.StartsWith(F) => "F"
                    }
                }

                expressionResults.Add(expressionResult);
            }
            else if (methodCallExpression.NodeType == ExpressionType.Call && methodCallExpression.Method.DeclaringType == typeof(Enumerable)) //stringArrayItems.Contains(x.Name)
            {
                WhereExpressionResult expressionResult = new WhereExpressionResult();
                expressionResult.SubProperty = methodCallExpression.Method.Name;

                Expression parameterExpression = methodCallExpression.Arguments.FirstOrDefault(x => x is MemberExpression && (x as MemberExpression).Expression.NodeType == ExpressionType.Parameter);

                expressionResult.MemberName = (parameterExpression as MemberExpression).Member.Name;

                Expression constantExpression = methodCallExpression.Arguments.FirstOrDefault(x => x is MemberExpression && (x as MemberExpression).Expression.NodeType == ExpressionType.Constant);

                MemberExpression memberExpression = constantExpression as MemberExpression;

                string expressionParameterKeyword = memberExpression.Member.Name;

                if (memberExpression.Type == typeof(string[]))
                {
                    object values = (memberExpression.Expression as ConstantExpression).Value;
                    object items  = values.GetType().GetField(expressionParameterKeyword).GetValue(values);

                    expressionResult.SubPropertyArguments.AddRange((items as string[])); // stringArrayItems.Contains(x.Name) => elements of "stringArrayItems"
                    expressionResult.SubPropertyArgumentType = typeof(string);
                }
                else if (memberExpression.Type == typeof(int[]))
                {
                    object values = (memberExpression.Expression as ConstantExpression).Value;
                    object items  = values.GetType().GetField(expressionParameterKeyword).GetValue(values);

                    expressionResult.SubPropertyArguments.AddRange((items as int[]).Select(x => x.ToString()).ToList());
                    expressionResult.SubPropertyArgumentType = typeof(int);
                }

                expressionResults.Add(expressionResult);
            }
            else if (methodCallExpression.NodeType == ExpressionType.Call)
            {
                WhereExpressionResult expressionResult = new WhereExpressionResult();
                expressionResult.SubProperty = methodCallExpression.Method.Name;
                expressionResult.MemberName  = (methodCallExpression.Arguments.FirstOrDefault() as MemberExpression).Member.Name;

                expressionResults.Add(expressionResult);
            }

            return(expressionResults);
        }