/// <summary> /// Load more items asynchronously. /// Controls which support incremental loading on such as GridView on Windows 8 /// call this method automatically. /// In other cases you should call this method yourself. /// </summary> /// <param name="token"> /// The cancellation token to be used to cancel the task. /// </param> /// <param name="count"> /// The number of items to load. /// This parameter overrides the pageSize specified in the constructore. /// </param> /// <returns>The result of loading the items.</returns> public async Task <int> LoadMoreItemsAsync(CancellationToken token, int count = 0) { if (busy) { throw new InvalidOperationException("Only one operation in flight at a time"); } busy = true; try { //check for cancellation if (token.IsCancellationRequested) { throw new OperationCanceledException(); } IMobileServiceTableQuery <TTable> query = this.query; if (count == 0) { count = PageSize; } //if still 0, PageSize was 0 if (count != 0) { query = query.Skip(itemsReceived).Take(count); } else { //disable paging if pagesize is 0 this.HasMoreItems = false; } int results = await this.ProcessQueryAsync(token, query); if (results == 0) { this.HasMoreItems = false; } else { this.itemsReceived += results; } //safe conversion since there can't be negative results return(results); } catch { // in case of error don't automatically try again this.HasMoreItems = false; throw; } finally { busy = false; } }
private async void RefreshQueryAsync() { // Temporarily disable the next/prev commands until this query finishes NextCommand.IsEnabled = false; PrevCommand.IsEnabled = false; List <Profile> profiles = await query.Skip(currentPage *profileCountPerPage).ToListAsync(); totalCount = ((ITotalCountProvider)profiles).TotalCount; Users.Clear(); Users.AddRange(profiles); EnableDisablePaging(); }
private async Task CreateQueryTest <MovieType, TExpectedException>( string name, Expression <Func <MovieType, bool> > whereClause, int?top = null, int?skip = null, OrderByClause[] orderBy = null, Expression <Func <MovieType, string> > selectExpression = null, bool?includeTotalCount = null, string odataExpression = null, bool useStringIdTable = false, Func <MovieType, bool> whereLambda = null) where MovieType : class, IMovie where TExpectedException : Exception { Log("### Executing {0}.", name); if (whereClause == null && whereLambda != null) { Assert.Fail("The argument 'whereLambda' is optional and can only be specified if 'whereClause' is also specified."); } try { var table = this.GetClient().GetTable <MovieType>(); IEnumerable <MovieType> readMovies = null; IEnumerable <string> readProjectedMovies = null; if (odataExpression == null) { IMobileServiceTableQuery <MovieType> query = null; IMobileServiceTableQuery <string> selectedQuery = null; if (whereClause != null) { query = table.Where(whereClause); } if (orderBy != null) { if (query == null) { query = table.Where(m => m.Duration == m.Duration); } query = ApplyOrdering(query, orderBy); } if (top.HasValue) { query = query == null?table.Take(top.Value) : query.Take(top.Value); } if (skip.HasValue) { query = query == null?table.Skip(skip.Value) : query.Skip(skip.Value); } if (selectExpression != null) { selectedQuery = query == null?table.Select(selectExpression) : query.Select(selectExpression); } if (includeTotalCount.HasValue) { query = query.IncludeTotalCount(); } if (selectedQuery == null) { // Both ways of querying should be equivalent, so using both with equal probability here. // TODO: Make it deterministic var tickCount = Environment.TickCount; if ((tickCount % 2) == 0) { Log("Querying using MobileServiceTableQuery<T>.ToEnumerableAsync"); readMovies = await query.ToEnumerableAsync(); } else { Log("Querying using IMobileServiceTable<T>.ReadAsync(MobileServiceTableQuery<U>)"); readMovies = await table.ReadAsync(query); } } else { readProjectedMovies = await selectedQuery.ToEnumerableAsync(); } } else { Log("Using the OData query directly"); JToken result = await table.ReadAsync(odataExpression); readMovies = result.ToObject <IEnumerable <MovieType> >(); } long actualTotalCount = -1; ITotalCountProvider totalCountProvider = (readMovies as ITotalCountProvider) ?? (readProjectedMovies as ITotalCountProvider); if (totalCountProvider != null) { actualTotalCount = totalCountProvider.TotalCount; } IEnumerable <MovieType> expectedData; if (useStringIdTable) { var movies = QueryTestData.TestMovies(); expectedData = new MovieType[movies.Length]; for (var i = 0; i < movies.Length; i++) { ((MovieType[])expectedData)[i] = (MovieType)(IMovie)movies[i]; } } else { expectedData = QueryTestData.TestIntIdMovies.Select(s => (MovieType)(IMovie)s); } // Due to a Xamarin.iOS bug, Expression.Compile() does not work for some expression trees, // in which case we allow the caller to provide a lambda directly and we use it instead of // compiling the expression tree. if (whereLambda != null) { expectedData = expectedData.Where(whereLambda); } else if (whereClause != null) { expectedData = expectedData.Where(whereClause.Compile()); } long expectedTotalCount = -1; if (includeTotalCount.HasValue && includeTotalCount.Value) { expectedTotalCount = expectedData.Count(); } if (orderBy != null) { expectedData = ApplyOrdering(expectedData, orderBy); } if (skip.HasValue) { expectedData = expectedData.Skip(skip.Value); } if (top.HasValue) { expectedData = expectedData.Take(top.Value); } if (includeTotalCount.HasValue) { if (expectedTotalCount != actualTotalCount) { Log("Total count was requested, but the returned value is incorrect: expected={0}, actual={1}", expectedTotalCount, actualTotalCount); Assert.Fail(""); return; } } List <string> errors = new List <string>(); bool expectedDataIsSameAsReadData; if (selectExpression != null) { string[] expectedProjectedData = expectedData.Select(selectExpression.Compile()).ToArray(); expectedDataIsSameAsReadData = Utilities.CompareArrays(expectedProjectedData, readProjectedMovies.ToArray(), errors); } else { expectedDataIsSameAsReadData = Utilities.CompareArrays(expectedData.ToArray(), readMovies.ToArray(), errors); } if (!expectedDataIsSameAsReadData) { foreach (var error in errors) { Log(error); } Log("Expected data is different"); Assert.Fail(""); return; } else { if (typeof(TExpectedException) == typeof(ExceptionTypeWhichWillNeverBeThrown)) { return; } else { Log("Error, test should have failed with {0}, but succeeded.", typeof(TExpectedException).FullName); Assert.Fail(""); return; } } } catch (TExpectedException ex) { Log("Caught expected exception - {0}: {1}", ex.GetType().FullName, ex.Message); return; } }
private static ZumoTest CreateQueryTest <TExpectedException>( string name, Expression <Func <Movie, bool> > whereClause, int?top = null, int?skip = null, OrderByClause[] orderBy = null, Expression <Func <Movie, string> > selectExpression = null, bool?includeTotalCount = null, string odataExpression = null) where TExpectedException : Exception { return(new ZumoTest(name, async delegate(ZumoTest test) { try { var table = ZumoTestGlobals.Instance.Client.GetTable <Movie>(); IEnumerable <Movie> readMovies = null; IEnumerable <string> readProjectedMovies = null; if (odataExpression == null) { IMobileServiceTableQuery <Movie> query = null; IMobileServiceTableQuery <string> selectedQuery = null; if (whereClause != null) { query = table.Where(whereClause); } if (orderBy != null) { if (query == null) { query = table.Where(m => m.Duration == m.Duration); } query = ApplyOrdering(query, orderBy); } if (top.HasValue) { query = query == null ? table.Take(top.Value) : query.Take(top.Value); } if (skip.HasValue) { query = query == null ? table.Skip(skip.Value) : query.Skip(skip.Value); } if (selectExpression != null) { selectedQuery = query == null ? table.Select(selectExpression) : query.Select(selectExpression); } if (includeTotalCount.HasValue) { query = query.IncludeTotalCount(); } if (selectedQuery == null) { // Both ways of querying should be equivalent, so using both with equal probability here. var tickCount = Environment.TickCount; if ((tickCount % 2) == 0) { test.AddLog("Querying using MobileServiceTableQuery<T>.ToEnumerableAsync"); readMovies = await query.ToEnumerableAsync(); } else { test.AddLog("Querying using IMobileServiceTable<T>.ReadAsync(MobileServiceTableQuery<U>)"); readMovies = await table.ReadAsync(query); } } else { readProjectedMovies = await selectedQuery.ToEnumerableAsync(); } } else { test.AddLog("Using the OData query directly"); JToken result = await table.ReadAsync(odataExpression); readMovies = result.ToObject <IEnumerable <Movie> >(); } long actualTotalCount = -1; ITotalCountProvider totalCountProvider = (readMovies as ITotalCountProvider) ?? (readProjectedMovies as ITotalCountProvider); if (totalCountProvider != null) { actualTotalCount = totalCountProvider.TotalCount; } IEnumerable <Movie> expectedData = ZumoQueryTestData.AllMovies; if (whereClause != null) { expectedData = expectedData.Where(whereClause.Compile()); } long expectedTotalCount = -1; if (includeTotalCount.HasValue && includeTotalCount.Value) { expectedTotalCount = expectedData.Count(); } if (orderBy != null) { expectedData = ApplyOrdering(expectedData, orderBy); } if (skip.HasValue) { expectedData = expectedData.Skip(skip.Value); } if (top.HasValue) { expectedData = expectedData.Take(top.Value); } if (includeTotalCount.HasValue) { if (expectedTotalCount != actualTotalCount) { test.AddLog("Total count was requested, but the returned value is incorrect: expected={0}, actual={1}", expectedTotalCount, actualTotalCount); return false; } } List <string> errors = new List <string>(); bool expectedDataIsSameAsReadData; if (selectExpression != null) { string[] expectedProjectedData = expectedData.Select(selectExpression.Compile()).ToArray(); expectedDataIsSameAsReadData = Util.CompareArrays(expectedProjectedData, readProjectedMovies.ToArray(), errors); } else { expectedDataIsSameAsReadData = Util.CompareArrays(expectedData.ToArray(), readMovies.ToArray(), errors); } if (!expectedDataIsSameAsReadData) { foreach (var error in errors) { test.AddLog(error); } test.AddLog("Expected data is different"); return false; } else { if (typeof(TExpectedException) == typeof(ExceptionTypeWhichWillNeverBeThrown)) { return true; } else { test.AddLog("Error, test should have failed with {0}, but succeeded.", typeof(TExpectedException).FullName); return false; } } } catch (TExpectedException ex) { test.AddLog("Caught expected exception - {0}: {1}", ex.GetType().FullName, ex.Message); return true; } })); }
private async Task CreateQueryTest <MovieType, TExpectedException>( string name, Expression <Func <MovieType, bool> > whereClause, int?top = null, int?skip = null, OrderByClause[] orderBy = null, Expression <Func <MovieType, string> > selectExpression = null, bool?includeTotalCount = null, string odataExpression = null, bool useStringIdTable = false, Func <MovieType, bool> whereLambda = null) where MovieType : class, IMovie where TExpectedException : Exception { Assert.False(whereClause == null && whereLambda != null); try { var table = this.GetClient().GetTable <MovieType>(); IEnumerable <MovieType> readMovies = null; IEnumerable <string> readProjectedMovies = null; if (odataExpression == null) { IMobileServiceTableQuery <MovieType> query = null; IMobileServiceTableQuery <string> selectedQuery = null; if (whereClause != null) { query = table.Where(whereClause); } if (orderBy != null) { if (query == null) { query = table.Where(m => m.Duration == m.Duration); } query = ApplyOrdering(query, orderBy); } if (top.HasValue) { query = query == null?table.Take(top.Value) : query.Take(top.Value); } if (skip.HasValue) { query = query == null?table.Skip(skip.Value) : query.Skip(skip.Value); } if (selectExpression != null) { selectedQuery = query == null?table.Select(selectExpression) : query.Select(selectExpression); } if (includeTotalCount.HasValue) { query = query.IncludeTotalCount(); } if (selectedQuery == null) { // Both ways of querying should be equivalent, so using both with equal probability here. // TODO: Make it deterministic var tickCount = Environment.TickCount; if ((tickCount % 2) == 0) { readMovies = await query.ToEnumerableAsync(); } else { readMovies = await table.ReadAsync(query); } } else { readProjectedMovies = await selectedQuery.ToEnumerableAsync(); } } else { JToken result = await table.ReadAsync(odataExpression); readMovies = result.ToObject <IEnumerable <MovieType> >(); } long actualTotalCount = -1; #pragma warning disable CS0618 // Type or member is obsolete ITotalCountProvider totalCountProvider = (readMovies as ITotalCountProvider) ?? (readProjectedMovies as ITotalCountProvider); #pragma warning restore CS0618 // Type or member is obsolete if (totalCountProvider != null) { actualTotalCount = totalCountProvider.TotalCount; } IEnumerable <MovieType> expectedData; if (useStringIdTable) { var movies = QueryTestData.TestMovies(); expectedData = new MovieType[movies.Length]; for (var i = 0; i < movies.Length; i++) { ((MovieType[])expectedData)[i] = (MovieType)(IMovie)movies[i]; } } else { expectedData = QueryTestData.TestIntIdMovies.Select(s => (MovieType)(IMovie)s); } // Due to a Xamarin.iOS bug, Expression.Compile() does not work for some expression trees, // in which case we allow the caller to provide a lambda directly and we use it instead of // compiling the expression tree. if (whereLambda != null) { expectedData = expectedData.Where(whereLambda); } else if (whereClause != null) { expectedData = expectedData.Where(whereClause.Compile()); } long expectedTotalCount = -1; if (includeTotalCount.HasValue && includeTotalCount.Value) { expectedTotalCount = expectedData.Count(); } if (orderBy != null) { expectedData = ApplyOrdering(expectedData, orderBy); } if (skip.HasValue) { expectedData = expectedData.Skip(skip.Value); } if (top.HasValue) { expectedData = expectedData.Take(top.Value); } if (includeTotalCount.HasValue) { Assert.Equal(expectedTotalCount, actualTotalCount); } List <string> errors = new List <string>(); bool expectedDataIsSameAsReadData; if (selectExpression != null) { string[] expectedProjectedData = expectedData.Select(selectExpression.Compile()).ToArray(); expectedDataIsSameAsReadData = Utilities.CompareArrays(expectedProjectedData, readProjectedMovies.ToArray(), errors); } else { expectedDataIsSameAsReadData = Utilities.CompareArrays(expectedData.ToArray(), readMovies.ToArray(), errors); } Assert.True(expectedDataIsSameAsReadData); if (typeof(TExpectedException) != typeof(ExceptionTypeWhichWillNeverBeThrown)) { Assert.True(false, "Test should have failed"); return; } } catch (TExpectedException) { return; } }
public IAsyncQuery <T> Skip(int count) { return(new AsyncQuery <T>(from.Skip(count))); }
/// <summary> /// Load more items asynchronously. /// Controls which support incremental loading on such as GridView on Windows 8 /// call this method automatically. /// In other cases you should call this method yourself. /// </summary> /// <param name="token"> /// The cancellation token to be used to cancel the task. /// </param> /// <param name="count"> /// The number of items to load. /// This parameter overrides the pageSize specified in the constructor. /// </param> /// <returns>The result of loading the items.</returns> public async Task <int> LoadMoreItemsAsync(CancellationToken token, int count = 0) { if (busy) { throw new InvalidOperationException(Resources.MobileServiceCollection_LoadInProcess); } busy = true; EventHandler loadingItems = LoadingItems; if (loadingItems != null) { loadingItems(this, new EventArgs()); } int results = 0; try { //check for cancellation if (token.IsCancellationRequested) { throw new OperationCanceledException(); } IMobileServiceTableQuery <TTable> query = this.query; if (count == 0) { count = PageSize; } //if still 0, PageSize was 0 if (count != 0) { query = query.Skip(itemsReceived).Take(count); } else { //disable paging if pagesize is 0 this.HasMoreItems = false; } results = await this.ProcessQueryAsync(token, query); if (results == 0) { this.HasMoreItems = false; } else { this.itemsReceived += results; } //safe conversion since there can't be negative results return(results); } catch { // in case of error don't automatically try again this.HasMoreItems = false; throw; } finally { busy = false; EventHandler <LoadingCompleteEventArgs> loadingComplete = LoadingComplete; if (loadingComplete != null) { loadingComplete(this, new LoadingCompleteEventArgs() { TotalItemsLoaded = results }); } } }