Esempio n. 1
0
        /// <summary>
        /// ConstantExpression visit method
        /// </summary>
        /// <param name="c">The ConstantExpression expression to visit</param>
        /// <returns>The visited ConstantExpression expression </returns>
        internal override Expression VisitConstant(ConstantExpression c)
        {
            if (c.Value == null)
            {
                this.builder.Append(UriHelper.NULL);
                return(c);
            }

            // DEVNOTE:
            // Rather than forcing every other codepath to have the 'Try...' pattern for formatting,
            // we catch the InvalidOperationException here to change the exception type.
            // This is exceedingly rare, and not a scenario where performance is meaningful, so the
            // reduced complexity in all other call sites is worth the extra logic here.
            string               result;
            BinaryExpression     b = this.parent as BinaryExpression;
            MethodCallExpression m = this.parent as MethodCallExpression;

            if ((b != null && HasEnumInBinaryExpression(b)) || (m != null && m.Method.Name == "HasFlag"))
            {
                c = this.ConvertConstantExpressionForEnum(c);
                ClientEdmModel       model          = this.context.Model;
                IEdmType             edmType        = model.GetOrCreateEdmType(c.Type.IsEnum() ? c.Type : c.Type.GetGenericArguments()[0]);
                ClientTypeAnnotation typeAnnotation = model.GetClientTypeAnnotation(edmType);
                string         typeNameInEdm        = this.context.ResolveNameFromTypeInternal(typeAnnotation.ElementType);
                MemberInfo     member      = typeAnnotation.ElementType.GetField(c.Value.ToString());
                string         memberValue = ClientTypeUtil.GetServerDefinedName(member);
                ODataEnumValue enumValue   = new ODataEnumValue(memberValue, typeNameInEdm ?? typeAnnotation.ElementTypeName);
                result = ODataUriUtils.ConvertToUriLiteral(enumValue, CommonUtil.ConvertToODataVersion(this.uriVersion), null);
            }
            else
            {
                try
                {
                    result = LiteralFormatter.ForConstants.Format(c.Value);
                }
                catch (InvalidOperationException)
                {
                    if (this.cantTranslateExpression)
                    {
                        // there's already a problem in the parents.
                        // we should just return here, because caller somewhere up the stack will throw a better exception
                        return(c);
                    }

                    throw new NotSupportedException(Strings.ALinq_CouldNotConvert(c.Value));
                }
            }

            Debug.Assert(result != null, "result != null");
            this.builder.Append(result);
            return(c);
        }