diff --git a/imgs/benchmarks.jpg b/imgs/benchmarks.jpg index fe8e393..28c2dbb 100644 Binary files a/imgs/benchmarks.jpg and b/imgs/benchmarks.jpg differ diff --git a/sandbox/AutoQuery.Benchmark/Benchmarks/QueryPerformance.cs b/sandbox/AutoQuery.Benchmark/Benchmarks/QueryPerformance.cs index 5e7c2af..7162c8d 100644 --- a/sandbox/AutoQuery.Benchmark/Benchmarks/QueryPerformance.cs +++ b/sandbox/AutoQuery.Benchmark/Benchmarks/QueryPerformance.cs @@ -55,11 +55,11 @@ public void AutoQuery_FilterSortSelectPage() PageSize = 10 }; - _autoQueryTestData.AsQueryable().ApplyQueryPaged(_queryProcessor, queryOptions).Datas.ToList(); + _autoQueryTestData.AsQueryable().ApplyQueryPaged(_queryProcessor, queryOptions).ToList(); } [Benchmark] - public void DynamicLinq_FilterSortSelectPageWith() + public void DynamicLinq_FilterSortSelectPage() { _dynamicLinqTestData.AsQueryable() .Where("Name == @0", "Name5000") @@ -71,7 +71,7 @@ public void DynamicLinq_FilterSortSelectPageWith() } [Benchmark] - public void AutoQuery_FilterSortPageWith() + public void AutoQuery_FilterSortPage() { var queryOptions = new TestQueryOptions { @@ -81,11 +81,11 @@ public void AutoQuery_FilterSortPageWith() PageSize = 10 }; - _autoQueryTestData.AsQueryable().ApplyQueryPaged(_queryProcessor, queryOptions).Datas.ToList(); + _autoQueryTestData.AsQueryable().ApplyQueryPaged(_queryProcessor, queryOptions).ToList(); } [Benchmark] - public void DynamicLinq_FilterSortPageWith() + public void DynamicLinq_FilterSortPage() { _dynamicLinqTestData.AsQueryable() .Where("Name == @0", "Name5000") @@ -96,7 +96,7 @@ public void DynamicLinq_FilterSortPageWith() } [Benchmark] - public void Sieve_FilterSortPageWith() + public void Sieve_FilterSortPage() { var sieveModel = new SieveModel { diff --git a/src/AutoQuery/Extensions/QueryExtensions.cs b/src/AutoQuery/Extensions/QueryExtensions.cs index 8fe02c9..28a39fd 100644 --- a/src/AutoQuery/Extensions/QueryExtensions.cs +++ b/src/AutoQuery/Extensions/QueryExtensions.cs @@ -43,7 +43,29 @@ public static IQueryable ApplyQuery(this IQueryable /// The query processor. /// The query options. /// The query object with conditions and pagination options applied. - public static PagedResult ApplyQueryPaged(this IQueryable query, IQueryProcessor queryProcessor, TQueryOptions queryOption) + public static IQueryable ApplyQueryPaged(this IQueryable query, IQueryProcessor queryProcessor, TQueryOptions queryOption) + where TQueryOptions : IQueryPagedOptions + where TData : class + { + var filterExpression = queryProcessor.BuildFilterExpression(queryOption); + var selectorExpression = queryProcessor.BuildSelectorExpression(queryOption); + if (filterExpression != null) + query = query.Where(filterExpression); + if (selectorExpression != null) + query = query.Select(selectorExpression); + return query.ApplySort(queryOption).ApplyPaging(queryOption); + } + + /// + /// Applies query conditions and pagination options. + /// + /// The type of the entity being queried. + /// The type of the query options. + /// The query object. + /// The query processor. + /// The query options. + /// The query object with conditions and pagination options applied. + public static PagedResult ApplyQueryPagedResult(this IQueryable query, IQueryProcessor queryProcessor, TQueryOptions queryOption) where TQueryOptions : IQueryPagedOptions where TData : class { diff --git a/test/AutoQuery.Tests/Extensions/QueryExtensionsTests.cs b/test/AutoQuery.Tests/Extensions/QueryExtensionsTests.cs index d92d4fc..15519b1 100644 --- a/test/AutoQuery.Tests/Extensions/QueryExtensionsTests.cs +++ b/test/AutoQuery.Tests/Extensions/QueryExtensionsTests.cs @@ -37,7 +37,7 @@ public void ApplyQuery_ShouldApplyFilterAndSelector(List data, TestQue [Theory] [ClassData(typeof(ApplyQueryPagedTestData))] - public void ApplyQueryPaged_ShouldApplyFilterSelectorAndPaging(List data, TestQueryPagedOptions queryOptions, Expression> filterExpression, Expression> selectorExpression, int expectedCount, int totalCount, int totalPages) + public void ApplyQueryPaged_ShouldApplyFilterSelectorAndPaging(List data, TestQueryPagedOptions queryOptions, Expression> filterExpression, Expression> selectorExpression, int expectedCount, string expectedName) { // Arrange var queryableData = data.AsQueryable(); @@ -50,10 +50,31 @@ public void ApplyQueryPaged_ShouldApplyFilterSelectorAndPaging(List da // Act var result = queryableData.ApplyQueryPaged(_queryProcessorMock.Object, queryOptions); + // Assert + Assert.Equal(expectedCount, result.Count()); + Assert.Equal(expectedName, result.First().Name); + } + + [Theory] + [ClassData(typeof(ApplyQueryPagedResultTestData))] + public void ApplyQueryPagedResult_ShouldApplyFilterSelectorAndPaging(List data, TestQueryPagedOptions queryOptions, Expression> filterExpression, Expression> selectorExpression, int expectedCount, int totalCount, int totalPages, string expectedName) + { + // Arrange + var queryableData = data.AsQueryable(); + + _queryProcessorMock.Setup(x => x.BuildFilterExpression(queryOptions)) + .Returns(filterExpression); + _queryProcessorMock.Setup(x => x.BuildSelectorExpression(queryOptions)) + .Returns(selectorExpression); + + // Act + var result = queryableData.ApplyQueryPagedResult(_queryProcessorMock.Object, queryOptions); + // Assert Assert.Equal(expectedCount, result.Datas.Count()); Assert.Equal(totalCount, result.Count); Assert.Equal(totalPages, result.TotalPages); + Assert.Equal(expectedName, result.Datas.First().Name); } [Theory] @@ -168,8 +189,58 @@ public IEnumerator GetEnumerator() (Expression>)(x => x.Id > 0), (Expression>)(x => new TestData { Id = x.Id, Name = x.Name }), 1, + "Test1" + }; + yield return new object[] + { + new List + { + new TestData { Id = 3, Name = "Test3" }, + new TestData { Id = 4, Name = "Test4" } + }, + new TestQueryPagedOptions { Page = 1, PageSize = 2 }, + (Expression>)(x => x.Id > 2), + (Expression>)(x => new TestData { Id = x.Id, Name = x.Name }), 2, - 2 + "Test3" + }; + yield return new object[] + { + new List + { + new TestData { Id = 5, Name = "Test5" }, + new TestData { Id = 6, Name = "Test6" }, + new TestData { Id = 7, Name = "Test7" } + }, + new TestQueryPagedOptions { Page = 2, PageSize = 2 }, + (Expression>)(x => x.Id > 4), + (Expression>)(x => new TestData { Id = x.Id, Name = x.Name }), + 1, + "Test7" + }; + } + + IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); + } + + public class ApplyQueryPagedResultTestData : IEnumerable + { + public IEnumerator GetEnumerator() + { + yield return new object[] + { + new List + { + new TestData { Id = 1, Name = "Test1" }, + new TestData { Id = 2, Name = "Test2" } + }, + new TestQueryPagedOptions { Page = 1, PageSize = 1 }, + (Expression>)(x => x.Id > 0), + (Expression>)(x => new TestData { Id = x.Id, Name = x.Name }), + 1, + 2, + 2, + "Test1" }; yield return new object[] { @@ -183,7 +254,8 @@ public IEnumerator GetEnumerator() (Expression>)(x => new TestData { Id = x.Id, Name = x.Name }), 2, 2, - 1 + 1, + "Test3" }; yield return new object[] { @@ -198,7 +270,8 @@ public IEnumerator GetEnumerator() (Expression>)(x => new TestData { Id = x.Id, Name = x.Name }), 1, 3, - 2 + 2, + "Test7" }; }