Example #1
0
        /// <summary>
        /// Get the path from the expression, including considering dictionary calls
        /// </summary>
        public Result GetPath(Expression expression)
        {
            expression = SimplifyExpression(expression);

            var callExpression = expression as MethodCallExpression;

            if (callExpression != null)
            {
                var customMethodResult = conventions.TranslateCustomQueryExpression(this, callExpression);
                if (customMethodResult != null)
                {
                    return(customMethodResult);
                }

                if (callExpression.Method.Name == "Count" && callExpression.Method.DeclaringType == typeof(Enumerable))
                {
                    if (callExpression.Arguments.Count != 1)
                    {
                        throw new ArgumentException("Not supported computation: " + callExpression +
                                                    ". You cannot use computation in RavenDB queries (only simple member expressions are allowed).");
                    }

                    var target = GetPath(callExpression.Arguments[0]);
                    return(new Result
                    {
                        MemberType = callExpression.Method.ReturnType,
                        IsNestedPath = false,
                        Path = target.Path + @".Count\(\)"
                    });
                }

                if (callExpression.Method.Name == "get_Item")
                {
                    var parent = GetPath(callExpression.Object);

                    return(new Result
                    {
                        MemberType = callExpression.Method.ReturnType,
                        IsNestedPath = false,
                        Path = parent.Path + "." +
                               GetValueFromExpression(callExpression.Arguments[0], callExpression.Method.GetParameters()[0].ParameterType)
                    });
                }

                throw new InvalidOperationException("Cannot understand how to translate " + callExpression);
            }

            var memberExpression = GetMemberExpression(expression);

            var customMemberResult = conventions.TranslateCustomQueryExpression(this, memberExpression);

            if (customMemberResult != null)
            {
                return(customMemberResult);
            }

            // we truncate the nullable .Value because in json all values are nullable
            if (memberExpression.Member.Name == "Value" &&
                Nullable.GetUnderlyingType(memberExpression.Expression.Type) != null)
            {
                return(GetPath(memberExpression.Expression));
            }


            AssertNoComputation(memberExpression);

            var result = new Result
            {
                Path          = memberExpression.ToString(),
                IsNestedPath  = memberExpression.Expression is MemberExpression,
                MemberType    = memberExpression.Member.GetMemberType(),
                MaybeProperty = memberExpression.Member as PropertyInfo
            };

            result.Path = HandlePropertyRenames(memberExpression.Member, result.Path);

            return(result);
        }