protected virtual async Task SortByTest(bool descendingOrder, bool useExpression, Func <ISortableRepository <Category>, Task <IEnumerable <Category> > > find) { // Create new empty database using (var connection = CreateConnection()) { InitializeDatabase(connection, "RepositoryTest_SortBy"); // Arrange var categories = new List <Category>(); for (int i = 0; i < 100; i++) { var category = new Category { Name = $"{i % 10}", Description = i.ToString() }; categories.Add(category); } ISortableRepository <Category> categoryRepository = CreateCategoryRepository(connection); await categoryRepository.CreateManyAsync(categories); // Act if (descendingOrder) { if (useExpression) { categoryRepository.SortByDescending("Name"); } else { categoryRepository.SortByDescending(p => p.Name); } } else if (useExpression) { categoryRepository.SortBy("Name"); } else { categoryRepository.SortBy(p => p.Name); } var result = (await find(categoryRepository)).ToList(); // Assert var sortedCategories = descendingOrder ? result.OrderByDescending(p => p.Name) : result.OrderBy(p => p.Name); Assert.NotNull(result); Assert.Equal(result, sortedCategories); } }
/// <summary> /// Sorts a queryable collection /// </summary> /// <param name="query">Queryable collection</param> /// <param name="sortable">Sortable repository</param> /// <typeparam name="TEntity">Entity type</typeparam> /// <returns>Sorted queryable collection</returns> public static IQueryable <TEntity> Sort <TEntity>( this IQueryable <TEntity> query, ISortableRepository <TEntity> sortable) where TEntity : class { if (query == null) { throw new ArgumentNullException(nameof(query)); } if (sortable == null) { throw new ArgumentNullException(nameof(sortable)); } if (string.IsNullOrEmpty(sortable.SortPropertyName)) { return(query); } if (sortable.SortOrder == SortOrder.Unspecified) { return(query); } var property = typeof(TEntity).GetProperty(sortable.SortPropertyName); var parameter = Expression.Parameter(typeof(TEntity), "p"); var propertyAccess = Expression.MakeMemberAccess(parameter, property); var orderByExp = Expression.Lambda(propertyAccess, parameter); var resultExp = Expression.Call( typeof(Queryable), sortable.SortOrder == SortOrder.Ascending ? "OrderBy" : "OrderByDescending", new[] { typeof(TEntity), property.PropertyType }, query.Expression, Expression.Quote(orderByExp)); return(query.Provider.CreateQuery <TEntity>(resultExp)); }