/// <summary> /// Evaluate a query and return its results. /// </summary> /// <typeparam name="U"> /// The type of element returned by the query. /// </typeparam> /// <param name="table"> /// Access to MobileServices table operations. /// </param> /// <param name="query"> /// The description of the query to evaluate and get the results for. /// </param> /// <returns>Results of the query.</returns> internal static Task <IEnumerable <U> > EvaluateQueryAsync <U>(IMobileServiceTable <T> table, MobileServiceTableQueryDescription query) { Debug.Assert(query != null, "query cannot be null!"); Debug.Assert(table != null, "table cannot be null!"); // Send the query string odata = query.ToString(); return(table.ReadAsync(odata, query.Parameters).ContinueWith(t => { // Parse the results long totalCount; JsonArray values = MobileServiceTable <T> .GetResponseSequence(t.Result, out totalCount); return (IEnumerable <U>) new TotalCountEnumerable <U>( totalCount, values.Select( item => { // Create and fill a new instance of the type we should // deserialize (which is either T or the input param // to the projection that will modify T). object obj = Activator.CreateInstance(query.ProjectionArgumentType ?? typeof(U)); MobileServiceTableSerializer.Deserialize(item, obj); // Apply the projection to the instance transforming it // as desired if (query.Projection != null) { obj = query.Projection.DynamicInvoke(obj); } return (U)obj; })); })); }
/// <summary> /// Initializes a new instance of the MobileServiceCollectionView /// class. /// </summary> /// <param name="table"> /// Table associated with the data source's query. /// </param> /// <param name="query">The query the data source represents.</param> internal MobileServiceCollectionView(MobileServiceTable <T> table, MobileServiceTableQueryDescription query) { Debug.Assert(table != null, "table cannot be null!"); Debug.Assert(query != null, "query cannot be null!"); this.table = table; this.query = query; // Evaluate the query immediately and start loading the data for it this.data = new List <T>(); this.EvaluateQueryAsync(); }
/// <summary> /// Evaluate the query and repopulate our collection with the results. /// </summary> private async void EvaluateQueryAsync() { // Invoke the query on the server and get our data IEnumerable <T> data = await MobileServiceTable <T> .EvaluateQueryAsync <T>(this.table, this.query); // Reset the collection with the new data this.data.Clear(); this.data.AddRange(data); this.OnCollectionChanged( new NotifyCollectionChangedEventArgs( NotifyCollectionChangedAction.Reset)); }
/// <summary> /// Initializes a new instance of the MobileServiceTableQuery class. /// </summary> /// <param name="table"> /// The table being queried. /// </param> /// <param name="includeTotalCount"> /// A value that if set will determine whether the query will request /// the total count for all the records that would have been returned /// ignoring any take paging/limit clause specified by client or /// server. /// </param> internal MobileServiceTableQuery(MobileServiceTable <T> table, bool includeTotalCount = false) { if (table == null) { throw new ArgumentNullException("table"); } this.Table = table; this.RequestTotalCount = includeTotalCount; // Create a default queryable to serve as the root this.Query = new T[0].AsQueryable(); }
public IMobileServiceTableQuery <U> Select <U>(Expression <Func <T, U> > selector) { if (selector == null) { throw new ArgumentNullException("selector"); } // Create a new table with the same name/client but // pretending to be of a different type since the query needs to // have the same type as the table. This won't cause any issues // since we're only going to use it to evaluate the query and it'll // never leak to users. MobileServiceTable <U> table = new MobileServiceTable <U>( this.Table.TableName, this.Table.MobileServiceClient); return(this.QueryProvider.Create(table, Queryable.Select(this.Query, selector), this.Parameters, this.RequestTotalCount)); }