Пример #1
0
        protected string GetHttpMethod(EntityStates state, ref Version requestVersion)
        {
            EntityStates states = state;

            if (states == EntityStates.Added)
            {
                return("POST");
            }
            if (states != EntityStates.Deleted)
            {
                if (states != EntityStates.Modified)
                {
                    throw System.Data.Services.Client.Error.InternalError(InternalError.UnvalidatedEntityState);
                }
            }
            else
            {
                return("DELETE");
            }
            if (Util.IsFlagSet(this.Options, SaveChangesOptions.ReplaceOnUpdate))
            {
                return("PUT");
            }
            if (Util.IsFlagSet(this.Options, SaveChangesOptions.PatchOnUpdate))
            {
                WebUtil.RaiseVersion(ref requestVersion, Util.DataServiceVersion3);
                return("PATCH");
            }
            return("MERGE");
        }
Пример #2
0
 internal void VisitCountOptions()
 {
     this.uriBuilder.Append('$');
     this.uriBuilder.Append("inlinecount");
     this.uriBuilder.Append('=');
     this.uriBuilder.Append("allpages");
     WebUtil.RaiseVersion(ref this.uriVersion, Util.DataServiceVersion2);
 }
Пример #3
0
 internal override Expression VisitResourceSetExpression(ResourceSetExpression rse)
 {
     if (rse.NodeType == ((ExpressionType)0x2711))
     {
         this.Visit(rse.Source);
         this.uriBuilder.Append('/').Append(this.ExpressionToString(rse.MemberExpression));
     }
     else
     {
         string entitySetName = (string)((ConstantExpression)rse.MemberExpression).Value;
         this.uriBuilder.Append(this.context.BaseUriResolver.GetEntitySetUri(entitySetName));
     }
     WebUtil.RaiseVersion(ref this.uriVersion, rse.UriVersion);
     if (rse.ResourceTypeAs != null)
     {
         this.uriBuilder.Append('/');
         this.uriBuilder.Append(System.Data.Services.Client.UriHelper.GetEntityTypeNameForUriAndValidateMaxProtocolVersion(rse.ResourceTypeAs, this.context, ref this.uriVersion));
     }
     if (rse.KeyPredicate != null)
     {
         this.uriBuilder.Append('(');
         if (rse.KeyPredicate.Count == 1)
         {
             this.uriBuilder.Append(this.ExpressionToString(rse.KeyPredicate.Values.First <ConstantExpression>()));
         }
         else
         {
             bool flag = false;
             foreach (KeyValuePair <PropertyInfo, ConstantExpression> pair in rse.KeyPredicate)
             {
                 if (flag)
                 {
                     this.uriBuilder.Append(',');
                 }
                 this.uriBuilder.Append(pair.Key.Name);
                 this.uriBuilder.Append('=');
                 this.uriBuilder.Append(this.ExpressionToString(pair.Value));
                 flag = true;
             }
         }
         this.uriBuilder.Append(')');
     }
     else if (rse == this.leafResourceSet)
     {
         this.uriBuilder.Append('(');
         this.uriBuilder.Append(')');
     }
     if (rse.CountOption == CountOption.ValueOnly)
     {
         this.uriBuilder.Append('/').Append('$').Append("count");
         WebUtil.RaiseVersion(ref this.uriVersion, Util.DataServiceVersion2);
     }
     this.VisitQueryOptions(rse);
     return(rse);
 }
Пример #4
0
        internal static string ExpressionToString(DataServiceContext context, Expression e, ref Version uriVersion)
        {
            ExpressionWriter writer = new ExpressionWriter(context);
            string           str    = writer.Translate(e);

            WebUtil.RaiseVersion(ref uriVersion, writer.uriVersion);
            if (writer.cantTranslateExpression)
            {
                throw new NotSupportedException(System.Data.Services.Client.Strings.ALinq_CantTranslateExpression(e.ToString()));
            }
            return(str);
        }
Пример #5
0
        private static Version DetermineRequestVersion(ClientTypeAnnotation clientType, EntityStates state)
        {
            if (state == EntityStates.Deleted)
            {
                return(Util.DataServiceVersion1);
            }
            Version version = Util.DataServiceVersion1;

            WebUtil.RaiseVersion(ref version, clientType.GetMetadataVersion());
            WebUtil.RaiseVersion(ref version, clientType.EpmMinimumDataServiceProtocolVersion.ToVersion());
            return(version);
        }
Пример #6
0
        /// <summary>
        /// Serializes an expression to a string
        /// </summary>
        /// <param name='context'>Data context used to generate type names for types.</param>
        /// <param name="e">Expression to serialize</param>
        /// <param name='inPath'>Whether or not the expression being written is part of the path of the URI.</param>
        /// <param name="uriVersion">the request data service version for the uri</param>
        /// <returns>serialized expression</returns>
        internal static string ExpressionToString(DataServiceContext context, Expression e, bool inPath, ref Version uriVersion)
        {
            ExpressionWriter ew         = new ExpressionWriter(context, inPath);
            string           serialized = ew.Translate(e);

            WebUtil.RaiseVersion(ref uriVersion, ew.uriVersion);
            if (ew.cantTranslateExpression)
            {
                throw new NotSupportedException(Strings.ALinq_CantTranslateExpression(e.ToString()));
            }

            return(serialized);
        }
Пример #7
0
 internal static string GetEntityTypeNameForUriAndValidateMaxProtocolVersion(Type type, DataServiceContext context, ref Version uriVersion)
 {
     if (context.MaxProtocolVersionAsVersion < Util.DataServiceVersion3)
     {
         throw new NotSupportedException(Strings.ALinq_TypeAsNotSupportedForMaxDataServiceVersionLessThan3);
     }
     if (!ClientTypeUtil.TypeOrElementTypeIsEntity(type))
     {
         throw new NotSupportedException(Strings.ALinq_TypeAsArgumentNotEntityType(type.FullName));
     }
     WebUtil.RaiseVersion(ref uriVersion, Util.DataServiceVersion3);
     return(context.ResolveNameFromType(type) ?? type.FullName);
 }
Пример #8
0
        /// <summary>
        /// ResourceSetExpression visit method.
        /// </summary>
        /// <param name="rse">ResourceSetExpression expression to visit</param>
        /// <returns>Visited ResourceSetExpression expression</returns>
        internal override Expression VisitResourceSetExpression(ResourceSetExpression rse)
        {
            if ((ResourceExpressionType)rse.NodeType == ResourceExpressionType.ResourceNavigationProperty)
            {
                this.Visit(rse.Source);
                this.uriBuilder.Append(UriHelper.FORWARDSLASH).Append(this.ExpressionToString(rse.MemberExpression, /*inPath*/ true));
            }
            else
            {
                // this is a resource set expression
                // we should be at the very begining of
                // the URI
                Debug.Assert(this.uriBuilder.Length == 0, "The builder is not empty while we are adding a resourset");
                string entitySetName = (String)((ConstantExpression)rse.MemberExpression).Value;
                this.uriBuilder.Append(this.context.BaseUriResolver.GetEntitySetUri(entitySetName));
            }

            WebUtil.RaiseVersion(ref this.uriVersion, rse.UriVersion);

            if (rse.ResourceTypeAs != null)
            {
                this.uriBuilder.Append(UriHelper.FORWARDSLASH);
                UriHelper.AppendTypeSegment(this.uriBuilder, rse.ResourceTypeAs, this.context, /*inPath*/ true, ref this.uriVersion);
            }

            if (rse.KeyPredicateConjuncts.Count > 0)
            {
                this.context.UrlConventions.AppendKeyExpression(rse.GetKeyProperties(), kvp => kvp.Key.Name, kvp => kvp.Value.Value, this.uriBuilder);
            }
            else if (rse == this.leafResourceSet)
            {
                // if resourceset is on the leaf, append ()
                this.uriBuilder.Append(UriHelper.LEFTPAREN);
                this.uriBuilder.Append(UriHelper.RIGHTPAREN);
            }

            if (rse.CountOption == CountOption.ValueOnly)
            {
                // append $count segment: /$count
                this.uriBuilder.Append(UriHelper.FORWARDSLASH).Append(UriHelper.DOLLARSIGN).Append(UriHelper.COUNT);
                WebUtil.RaiseVersion(ref this.uriVersion, Util.DataServiceVersion2);
            }

            this.VisitQueryOptions(rse);
            return(rse);
        }
Пример #9
0
        /// <summary>Gets the type name to be used in the URI for the given <paramref name="type"/>.</summary>
        /// <param name="type">Type to get name for.</param>
        /// <param name="context">Data context used to generate type names for types.</param>
        /// <param name="uriVersion">Data service version for the uri</param>
        /// <returns>The name for the <paramref name="type"/>, suitable for including in a URI.</returns>
        internal static string GetEntityTypeNameForUriAndValidateMaxProtocolVersion(Type type, DataServiceContext context, ref Version uriVersion)
        {
            Debug.Assert(type != null, "type != null");
            Debug.Assert(context != null, "context != null");

            if (context.MaxProtocolVersionAsVersion < Util.DataServiceVersion3)
            {
                throw new NotSupportedException(Strings.ALinq_TypeAsNotSupportedForMaxDataServiceVersionLessThan3);
            }

            if (!ClientTypeUtil.TypeOrElementTypeIsEntity(type))
            {
                throw new NotSupportedException(Strings.ALinq_TypeAsArgumentNotEntityType(type.FullName));
            }

            // Raise the uriVersion each time we write the type segment on the uri.
            WebUtil.RaiseVersion(ref uriVersion, Util.DataServiceVersion3);
            return(context.ResolveNameFromType(type) ?? type.FullName);
        }
Пример #10
0
        internal void VisitProjectionPaths(List <string> paths)
        {
            this.uriBuilder.Append('$');
            this.uriBuilder.Append("select");
            this.uriBuilder.Append('=');
            int num = 0;

            while (true)
            {
                string str = paths[num];
                this.uriBuilder.Append(str);
                if (++num == paths.Count)
                {
                    break;
                }
                this.uriBuilder.Append(',');
            }
            WebUtil.RaiseVersion(ref this.uriVersion, Util.DataServiceVersion2);
        }
Пример #11
0
        /// <summary>
        /// ProjectionPaths visit method.
        /// </summary>
        /// <param name="paths">Projection Paths</param>
        internal void VisitProjectionPaths(List <string> paths)
        {
            StringBuilder tmpBuilder = new StringBuilder();
            int           ii         = 0;

            while (true)
            {
                string path = paths[ii];

                tmpBuilder.Append(path);

                if (++ii == paths.Count)
                {
                    break;
                }

                tmpBuilder.Append(UriHelper.COMMA);
            }

            this.AddAsCachedQueryOption(UriHelper.DOLLARSIGN + UriHelper.OPTIONSELECT, tmpBuilder.ToString());
            WebUtil.RaiseVersion(ref this.uriVersion, Util.DataServiceVersion2);
        }
Пример #12
0
        internal void VisitCustomQueryOptions(Dictionary <ConstantExpression, ConstantExpression> options)
        {
            List <ConstantExpression> list  = options.Keys.ToList <ConstantExpression>();
            List <ConstantExpression> list2 = options.Values.ToList <ConstantExpression>();
            int num = 0;

            while (true)
            {
                this.uriBuilder.Append(list[num].Value);
                this.uriBuilder.Append('=');
                this.uriBuilder.Append(list2[num].Value);
                string str = list[num].Value.ToString();
                if (str.Equals('$' + "inlinecount", StringComparison.Ordinal) || str.Equals('$' + "select", StringComparison.Ordinal))
                {
                    WebUtil.RaiseVersion(ref this.uriVersion, Util.DataServiceVersion2);
                }
                if (++num == list.Count)
                {
                    return;
                }
                this.uriBuilder.Append('&');
            }
        }
Пример #13
0
        /// <summary>
        /// Append all cached query options to uri.
        /// </summary>
        private void AppendCachedQueryOptionsToUriBuilder()
        {
            int i = 0;

            foreach (var queryOption in this.cachedQueryOptions)
            {
                if (i++ != 0)
                {
                    this.uriBuilder.Append(UriHelper.AMPERSAND);
                }

                string keyStr   = queryOption.Key;
                string valueStr = string.Join(",", queryOption.Value);
                this.uriBuilder.Append(keyStr);
                this.uriBuilder.Append(UriHelper.EQUALSSIGN);
                this.uriBuilder.Append(valueStr);

                if (keyStr.Equals(UriHelper.DOLLARSIGN + UriHelper.OPTIONCOUNT, StringComparison.Ordinal) ||
                    keyStr.Equals(UriHelper.DOLLARSIGN + UriHelper.OPTIONSELECT, StringComparison.Ordinal))
                {
                    WebUtil.RaiseVersion(ref this.uriVersion, Util.DataServiceVersion2);
                }
            }
        }
Пример #14
0
 internal void RaiseUriVersion(Version newVersion)
 {
     WebUtil.RaiseVersion(ref this.uriVersion, newVersion);
 }
Пример #15
0
 /// <summary>
 /// VisitCountOptions visit method.
 /// </summary>
 internal void VisitCountOptions()
 {
     this.AddAsCachedQueryOption(UriHelper.DOLLARSIGN + UriHelper.OPTIONCOUNT, UriHelper.COUNTALL);
     WebUtil.RaiseVersion(ref this.uriVersion, Util.DataServiceVersion2);
 }
Пример #16
0
        internal override Expression VisitMethodCall(MethodCallExpression m)
        {
            string         str;
            SequenceMethod method;

            if (TypeSystem.TryGetQueryOptionMethod(m.Method, out str))
            {
                this.builder.Append(str);
                this.builder.Append('(');
                if (str == "substringof")
                {
                    this.Visit(m.Arguments[0]);
                    this.builder.Append(',');
                    this.Visit(m.Object);
                }
                else
                {
                    if (m.Object != null)
                    {
                        this.Visit(m.Object);
                    }
                    if (m.Arguments.Count > 0)
                    {
                        if (m.Object != null)
                        {
                            this.builder.Append(',');
                        }
                        for (int i = 0; i < m.Arguments.Count; i++)
                        {
                            this.Visit(m.Arguments[i]);
                            if (i < (m.Arguments.Count - 1))
                            {
                                this.builder.Append(',');
                            }
                        }
                    }
                }
                this.builder.Append(')');
                return(m);
            }
            if (ReflectionUtil.TryIdentifySequenceMethod(m.Method, out method))
            {
                if (ReflectionUtil.IsAnyAllMethod(method))
                {
                    WebUtil.RaiseVersion(ref this.uriVersion, Util.DataServiceVersion3);
                    this.Visit(m.Arguments[0]);
                    this.builder.Append('/');
                    if (method == SequenceMethod.All)
                    {
                        this.builder.Append("all");
                    }
                    else
                    {
                        this.builder.Append("any");
                    }
                    this.builder.Append('(');
                    if (method != SequenceMethod.Any)
                    {
                        LambdaExpression expression = (LambdaExpression)m.Arguments[1];
                        string           name       = expression.Parameters[0].Name;
                        this.builder.Append(name);
                        this.builder.Append(':');
                        this.scopeCount++;
                        this.Visit(expression.Body);
                        this.scopeCount--;
                    }
                    this.builder.Append(')');
                    return(m);
                }
                if ((method == SequenceMethod.OfType) && (this.parent != null))
                {
                    MethodCallExpression parent = this.parent as MethodCallExpression;
                    if (((parent != null) && ReflectionUtil.TryIdentifySequenceMethod(parent.Method, out method)) && ReflectionUtil.IsAnyAllMethod(method))
                    {
                        Type type = parent.Method.GetGenericArguments().SingleOrDefault <Type>();
                        if (ClientTypeUtil.TypeOrElementTypeIsEntity(type))
                        {
                            this.Visit(m.Arguments[0]);
                            this.builder.Append('/');
                            this.builder.Append(System.Data.Services.Client.UriHelper.GetEntityTypeNameForUriAndValidateMaxProtocolVersion(type, this.context, ref this.uriVersion));
                            return(m);
                        }
                    }
                }
            }
            this.cantTranslateExpression = true;
            return(m);
        }
Пример #17
0
        /// <summary>
        /// MethodCallExpression visit method
        /// </summary>
        /// <param name="m">The MethodCallExpression expression to visit</param>
        /// <returns>The visited MethodCallExpression expression </returns>
        internal override Expression VisitMethodCall(MethodCallExpression m)
        {
            string methodName;

            if (TypeSystem.TryGetQueryOptionMethod(m.Method, out methodName))
            {
                this.builder.Append(methodName);
                this.builder.Append(UriHelper.LEFTPAREN);

                // There is a single function, 'substringof', which reorders its argument with
                // respect to the CLR method. Thus handling it as a special case rather than
                // using a more general argument reordering mechanism.
                if (methodName == "substringof")
                {
                    Debug.Assert(m.Method.Name == "Contains", "m.Method.Name == 'Contains'");
                    Debug.Assert(m.Object != null, "m.Object != null");
                    Debug.Assert(m.Arguments.Count == 1, "m.Arguments.Count == 1");
                    this.Visit(m.Arguments[0]);
                    this.builder.Append(UriHelper.COMMA);
                    this.Visit(m.Object);
                }
                else
                {
                    if (m.Object != null)
                    {
                        this.Visit(m.Object);
                    }

                    if (m.Arguments.Count > 0)
                    {
                        if (m.Object != null)
                        {
                            this.builder.Append(UriHelper.COMMA);
                        }

                        for (int ii = 0; ii < m.Arguments.Count; ii++)
                        {
                            this.Visit(m.Arguments[ii]);
                            if (ii < m.Arguments.Count - 1)
                            {
                                this.builder.Append(UriHelper.COMMA);
                            }
                        }
                    }
                }

                this.builder.Append(UriHelper.RIGHTPAREN);
            }
            else
            {
                SequenceMethod sequenceMethod;
                if (ReflectionUtil.TryIdentifySequenceMethod(m.Method, out sequenceMethod))
                {
                    if (ReflectionUtil.IsAnyAllMethod(sequenceMethod))
                    {
                        // Raise the uriVersion each time we write any or all methods to the uri.
                        WebUtil.RaiseVersion(ref this.uriVersion, Util.DataServiceVersion3);

                        this.Visit(m.Arguments[0]);
                        this.builder.Append(UriHelper.FORWARDSLASH);
                        if (sequenceMethod == SequenceMethod.All)
                        {
                            this.builder.Append(XmlConstants.AllMethodName);
                        }
                        else
                        {
                            this.builder.Append(XmlConstants.AnyMethodName);
                        }

                        this.builder.Append(UriHelper.LEFTPAREN);
                        if (sequenceMethod != SequenceMethod.Any)
                        {
                            // SequenceMethod.Any represents Enumerable.Any(), which has only source argument
                            // AnyPredicate and All has a second parameter which is the predicate lambda.
                            Debug.Assert(m.Arguments.Count() == 2, "m.Arguments.Count() == 2");
                            LambdaExpression le            = (LambdaExpression)m.Arguments[1];
                            string           rangeVariable = le.Parameters[0].Name;
                            this.builder.Append(rangeVariable);
                            this.builder.Append(UriHelper.COLON);
                            this.scopeCount++;
                            this.Visit(le.Body);
                            this.scopeCount--;
                        }

                        this.builder.Append(UriHelper.RIGHTPAREN);
                        return(m);
                    }
                    else if (sequenceMethod == SequenceMethod.OfType && this.parent != null)
                    {
                        // check to see if this is an OfType filter for Any or All.
                        // e.g. ctx.CreateQuery<Movie>("Movies").Where(m=>m.Actors.OfType<MegaStar>().Any())
                        //      which translates to /Movies()?$filter=Actors/MegaStar/any()
                        MethodCallExpression mce = this.parent as MethodCallExpression;
                        if (mce != null &&
                            ReflectionUtil.TryIdentifySequenceMethod(mce.Method, out sequenceMethod) &&
                            ReflectionUtil.IsAnyAllMethod(sequenceMethod))
                        {
                            Type filteredType = mce.Method.GetGenericArguments().SingleOrDefault();
                            if (ClientTypeUtil.TypeOrElementTypeIsEntity(filteredType))
                            {
                                this.Visit(m.Arguments[0]);
                                this.builder.Append(UriHelper.FORWARDSLASH);

                                UriHelper.AppendTypeSegment(this.builder, filteredType, this.context, this.inPath, ref this.uriVersion);

                                return(m);
                            }
                        }
                    }
                }

                this.cantTranslateExpression = true;
            }

            return(m);
        }
Пример #18
0
 /// <summary>Raise the UriVersion if it is lower than <paramref name="newVersion"/>.</summary>
 /// <param name="newVersion">Uri version from the expand and projection paths</param>
 internal void RaiseUriVersion(Version newVersion)
 {
     Debug.Assert(newVersion != null, "newVersion != null");
     WebUtil.RaiseVersion(ref this.uriVersion, newVersion);
 }