예제 #1
0
        /// <inheritdoc />
        protected override Expression VisitMethodCall(MethodCallExpression expression)
        {
            LogWriter.WriteLine($"VisitMethodCall: {expression}, method {expression.Method.Name}, args: {string.Join(", ",expression.Arguments.Select(a => a.ToString()))}");

            var method = expression.Method;

            switch (method.Name)
            {
            case "Contains":
            case "StartsWith":
            case "EndsWith":
                var obj     = Evaluate(expression.Object);
                var pattern = Evaluate(expression.Arguments[0]);

                _state.SetColumn(obj.ToString());
                _state.SetFunction(method.Name, pattern);

                return(expression);

            case "Min":
            case "Max":
            case "Count":
            case "Average":
            case "Sum":
                using (_state.PushCollectorMode(QueryCollectionState.Aggregate))
                {
                    object value = null;

                    if (expression.Arguments.Count > 1)
                    {
                        throw new InvalidOperationException($"Unsupported number of aggregate function arguments: {expression.Arguments.Count}");
                    }
                    if (expression.Arguments.Count > 0)
                    {
                        value = Evaluate(expression.Arguments[0]);
                    }

                    _state.SetFunction(method.Name, value);
                }

                return(expression);

            case "Column":
                var columnName = Evaluate(expression.Arguments[0]).ToString();

                _arguments.Push(columnName);
                _state.SetColumn(columnName);

                return(expression);
            }

            return(base.VisitMethodCall(expression));            // throws
        }
예제 #2
0
        /// <inheritdoc />
        public override void VisitResultOperator(ResultOperatorBase resultOperator, QueryModel queryModel, int index)
        {
            LogWriter.WriteLine($"VisitResultOperator: {resultOperator}, type {resultOperator.GetType().Name}");

            switch (resultOperator)
            {
            // First()
            case FirstResultOperator _:
                _collector.Take = 1;
                break;

            // Count()
            case CountResultOperator _:
            case LongCountResultOperator _:
                _collector.SetResultAggregationType(AggregationTypeStrict.Count);
                break;

            // Take()
            case TakeResultOperator takeOperator:
                var takeExpr = takeOperator.Count;

                if (takeExpr.NodeType == ExpressionType.Constant)
                {
                    _collector.Take = (int)((ConstantExpression)takeExpr).Value;
                }
                else
                {
                    throw new NotSupportedException("Currently not supporting methods or variables in the Skip or Take clause.");
                }

                break;

            // Skip()
            case SkipResultOperator skipOperator:
                var skipExpr = skipOperator.Count;

                if (skipExpr.NodeType == ExpressionType.Constant)
                {
                    _collector.Skip = (int)((ConstantExpression)skipExpr).Value;
                }
                else
                {
                    throw new NotSupportedException("Currently not supporting methods or variables in the Skip or Take clause.");
                }

                break;

            // Min()
            case MinResultOperator _:
                _state.SetFunction("Min", null);
                break;

            // Max()
            case MaxResultOperator _:
                _state.SetFunction("Max", null);
                break;

            // Average()
            case AverageResultOperator _:
                _state.SetFunction("Average", null);
                break;

            // GroupBy()
            case GroupResultOperator groupOperator:
                using (_state.PushCollectorMode(QueryCollectionState.GroupBy))
                {
                    var key             = groupOperator.KeySelector;
                    var elementSelector = groupOperator.ElementSelector;

                    UpdateEntitySchemaQueryExpression(key);
                    UpdateEntitySchemaQueryExpression(elementSelector);

                    if (key is NewExpression newKeySelector)
                    {
                        int position = 0;
                        foreach (var memberInfo in newKeySelector.Members)
                        {
                            _state.SetColumnAlias(position++, memberInfo.Name);
                        }
                    }
                }

                break;
            }
        }