/// <summary> /// Get an element from a table by its id. /// </summary> /// <param name="id"> /// The id of the element. /// </param> /// <param name="parameters"> /// A dictionary of user-defined parameters and values to include in /// the request URI query string. /// </param> /// <returns> /// The desired element as JSON object. /// </returns> private async Task <JObject> GetSingleValueAsync(object id, IDictionary <string, string> parameters) { Arguments.IsNotNull(id, nameof(id)); // Create a query for just this item string query = $"$filter=({MobileServiceSystemColumns.Id} eq {ODataExpressionVisitor.ToODataConstant(id)})"; // Send the query QueryResult response = await ReadAsync(query, parameters, MobileServiceFeatures.TypedTable); return(GetSingleValue(response)); }
/// <summary> /// Get an element from a table by its id. /// </summary> /// <param name="id"> /// The id of the element. /// </param> /// <param name="parameters"> /// A dictionary of user-defined parameters and values to include in /// the request URI query string. /// </param> /// <returns> /// The desired element as JSON object. /// </returns> private async Task <JObject> GetSingleValueAsync(object id, IDictionary <string, string> parameters) { Debug.Assert(id != null); // Create a query for just this item string query = string.Format( CultureInfo.InvariantCulture, "$filter=({0} eq {1})", MobileServiceSystemColumns.Id, ODataExpressionVisitor.ToODataConstant(id)); // Send the query QueryResult response = await this.ReadAsync(query, parameters, MobileServiceFeatures.TypedTable); return(GetSingleValue(response)); }
/// <summary> /// Returns the next-page token to put in the $skiptoken query option. /// </summary> /// <param name="enumerator">Enumerator for which the continuation token is being requested.</param> /// <returns>The next-page token as a collection of primitive types.</returns> public virtual object[] GetContinuationToken(IEnumerator enumerator) { if (this.lastReceivedPage == null) { return(null); } var operation = new ODataExpressionVisitor(this.expression).Eval(); var compound = operation as ODataCompoundQueryOperation; if (compound != null) { var partial = (this.queryProvider.GetType().InvokeMember("ExecuteQuery", BindingFlags.InvokeMethod, null, this.queryProvider, new object[] { compound.AnonymousGetManyOperation }) as IEnumerable <object>).First(); compound.OfType = partial.GetType().TypeOrElementType(); compound.Keys = partial.DataServiceKeys(); } if (operation != null) { operation.TopCount = 0; operation.SkipCount = 0; operation.ContinuationToken = null; operation.IsCountRequest = true; this.queryProvider.GetType().GetProperty("SkipTakeBasedPaging").SetValue(this.queryProvider, false, null); var @return = operation is ODataSelectManyQueryOperation ? (operation as ODataSelectManyQueryOperation).NavigationPropertyType : operation.OfType; var queryProviderType = typeof(ODataQueryProvider <>).MakeGenericType(@return); var result = (long)queryProviderType.InvokeMember("ExecuteQuery", BindingFlags.InvokeMethod, null, this.queryProvider, new object[] { operation }); if ((this.lastReceivedPage * this.PageSizeFor(@return)) + this.CurrentOffset() >= result) { return(null); } var token = string.Format(CultureInfo.InvariantCulture, "{0}:{1}", this.entityTypeName, this.lastReceivedPage + 1); return(new object[] { Convert.ToBase64String(Encoding.Default.GetBytes(token)) }); } return(null); }
/// <summary> /// Returns the next-page token to put in the $skiptoken query option. /// </summary> /// <param name="enumerator">Enumerator for which the continuation token is being requested.</param> /// <returns>The next-page token as a collection of primitive types.</returns> public virtual object[] GetContinuationToken(IEnumerator enumerator) { if (this.lastReceivedPage == null) return null; var operation = new ODataExpressionVisitor(this.expression).Eval(); var compound = operation as ODataCompoundQueryOperation; if (compound != null) { var partial = (this.queryProvider.GetType().InvokeMember("ExecuteQuery", BindingFlags.InvokeMethod, null, this.queryProvider, new object[] { compound.AnonymousGetManyOperation }) as IEnumerable<object>).First(); compound.OfType = partial.GetType().TypeOrElementType(); compound.Keys = partial.DataServiceKeys(); } if (operation != null) { operation.TopCount = 0; operation.SkipCount = 0; operation.ContinuationToken = null; operation.IsCountRequest = true; this.queryProvider.GetType().GetProperty("SkipTakeBasedPaging").SetValue(this.queryProvider, false, null); var @return = operation is ODataSelectManyQueryOperation ? (operation as ODataSelectManyQueryOperation).NavigationPropertyType : operation.OfType; var queryProviderType = typeof(ODataQueryProvider<>).MakeGenericType(@return); var result = (long)queryProviderType.InvokeMember("ExecuteQuery", BindingFlags.InvokeMethod, null, this.queryProvider, new object[] { operation }); if ((this.lastReceivedPage * this.PageSizeFor(@return)) + this.CurrentOffset() >= result) return null; var token = string.Format(CultureInfo.InvariantCulture, "{0}:{1}", this.entityTypeName, this.lastReceivedPage + 1); return new object[] { Convert.ToBase64String(Encoding.Default.GetBytes(token)) }; } return null; }
/// <summary> /// Convert the query structure into the standard OData URI protocol /// for queries. /// </summary> /// <returns> /// URI fragment representing the query. /// </returns> public string ToODataString() { char? separator = null; StringBuilder text = new StringBuilder(); // Add the filter if (this.Filter != null) { string filterStr = ODataExpressionVisitor.ToODataString(this.Filter); text.AppendFormat(CultureInfo.InvariantCulture, "{0}{1}={2}", separator, ODataOptions.Filter, filterStr); separator = '&'; } // Add the ordering if (this.Ordering.Count > 0) { IEnumerable <string> orderings = this.Ordering .Select(o => { string result = ODataExpressionVisitor.ToODataString(o.Expression); if (o.Direction == OrderByDirection.Descending) { result += " desc"; } return(result); }); text.AppendFormat(CultureInfo.InvariantCulture, "{0}{1}={2}", separator, ODataOptions.OrderBy, string.Join(",", orderings.ToArray())); separator = '&'; } // Skip any elements if (this.Skip.HasValue && this.Skip >= 0) { text.AppendFormat(CultureInfo.InvariantCulture, "{0}{1}={2}", separator, ODataOptions.Skip, this.Skip); separator = '&'; } // Take the desired number of elements if (this.Top.HasValue && this.Top >= 0) { text.AppendFormat(CultureInfo.InvariantCulture, "{0}{1}={2}", separator, ODataOptions.Top, this.Top); separator = '&'; } // Add the selection if (this.Selection.Count > 0) { text.AppendFormat(CultureInfo.InvariantCulture, "{0}{1}={2}", separator, ODataOptions.Select, string.Join(",", this.Selection.Select <string, string>(Uri.EscapeDataString).ToArray <string>())); separator = '&'; } // Add the total count if (this.IncludeTotalCount) { text.AppendFormat(CultureInfo.InvariantCulture, "{0}{1}=allpages", separator, ODataOptions.InlineCount); separator = '&'; } return(text.ToString()); }
public void ToODataString_Null_ReturnsEmpty() { Assert.Equal("", ODataExpressionVisitor.ToODataString(null)); }