added sortings.
This commit is contained in:
		
							parent
							
								
									a3139cb892
								
							
						
					
					
						commit
						7bdb84e896
					
				| @ -4,6 +4,7 @@ using PoweredSoft.DynamicLinq.Extensions; | ||||
| using PoweredSoft.DynamicLinq.Fluent; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Data.SqlClient; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| @ -65,5 +66,34 @@ namespace PoweredSoft.DynamicLinq.Test | ||||
|             query = queryBuilder.Build(); | ||||
|             Assert.AreEqual(2, query.Count()); | ||||
|         } | ||||
| 
 | ||||
|         [TestMethod] | ||||
|         public void TestingSort() | ||||
|         { | ||||
|             // subject. | ||||
|             var posts = new List<Post>() | ||||
|             { | ||||
|                 new Post { Id = 1, AuthorId = 1, Title = "Hello 1", Content = "World" }, | ||||
|                 new Post { Id = 2, AuthorId = 1, Title = "Hello 2", Content = "World" }, | ||||
|                 new Post { Id = 3, AuthorId = 2, Title = "Hello 3", Content = "World" }, | ||||
|             }; | ||||
| 
 | ||||
|             // the query. | ||||
|             var query = posts.AsQueryable(); | ||||
|             var queryBuilder = new QueryBuilder<Post>(query); | ||||
| 
 | ||||
|             // add some sorting. | ||||
|             queryBuilder | ||||
|                 .OrderByDescending("AuthorId") | ||||
|                 .ThenBy("Id"); | ||||
| 
 | ||||
|             query = queryBuilder.Build(); | ||||
| 
 | ||||
|             var first = query.First(); | ||||
|             var second = query.Skip(1).First(); | ||||
| 
 | ||||
|             Assert.IsTrue(first.Id == 3); | ||||
|             Assert.IsTrue(second.Id == 1); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -49,6 +49,7 @@ | ||||
|     </Reference> | ||||
|     <Reference Include="System" /> | ||||
|     <Reference Include="System.Core" /> | ||||
|     <Reference Include="System.Data" /> | ||||
|   </ItemGroup> | ||||
|   <ItemGroup> | ||||
|     <Compile Include="ComplexQueryTest.cs" /> | ||||
|  | ||||
| @ -91,7 +91,7 @@ namespace PoweredSoft.DynamicLinq.Test | ||||
|         public void LessThen() | ||||
|         { | ||||
|             // subject. | ||||
|             var authors = new List<Post>() | ||||
|             var posts = new List<Post>() | ||||
|             { | ||||
|                 new Post { Id = 1, AuthorId = 1, Title = "Hello 1", Content = "World" }, | ||||
|                 new Post { Id = 2, AuthorId = 1, Title = "Hello 2", Content = "World" }, | ||||
| @ -99,7 +99,7 @@ namespace PoweredSoft.DynamicLinq.Test | ||||
|             }; | ||||
| 
 | ||||
|             // the query. | ||||
|             var query = authors.AsQueryable(); | ||||
|             var query = posts.AsQueryable(); | ||||
| 
 | ||||
|             // simple where. | ||||
|             var newQuery = query.Where("AuthorId", ConditionOperators.LessThan, 2); | ||||
| @ -112,7 +112,7 @@ namespace PoweredSoft.DynamicLinq.Test | ||||
|         public void GreaterThanOrEqual() | ||||
|         { | ||||
|             // subject. | ||||
|             var authors = new List<Post>() | ||||
|             var posts = new List<Post>() | ||||
|             { | ||||
|                 new Post { Id = 1, AuthorId = 1, Title = "Hello 1", Content = "World" }, | ||||
|                 new Post { Id = 2, AuthorId = 1, Title = "Hello 2", Content = "World" }, | ||||
| @ -120,7 +120,7 @@ namespace PoweredSoft.DynamicLinq.Test | ||||
|             }; | ||||
| 
 | ||||
|             // the query. | ||||
|             var query = authors.AsQueryable(); | ||||
|             var query = posts.AsQueryable(); | ||||
| 
 | ||||
|             // simple where. | ||||
|             var newQuery = query.Where("AuthorId", ConditionOperators.GreaterThanOrEqual, 2); | ||||
| @ -128,5 +128,28 @@ namespace PoweredSoft.DynamicLinq.Test | ||||
|             // must match. | ||||
|             Assert.AreEqual(1, newQuery.Count()); | ||||
|         } | ||||
| 
 | ||||
|         [TestMethod] | ||||
|         public void TestingSort() | ||||
|         { | ||||
|             // subject. | ||||
|             var posts = new List<Post>() | ||||
|             { | ||||
|                 new Post { Id = 1, AuthorId = 1, Title = "Hello 1", Content = "World" }, | ||||
|                 new Post { Id = 2, AuthorId = 1, Title = "Hello 2", Content = "World" }, | ||||
|                 new Post { Id = 3, AuthorId = 2, Title = "Hello 3", Content = "World" }, | ||||
|             }; | ||||
| 
 | ||||
|             // the query. | ||||
|             var query = posts.AsQueryable(); | ||||
|             query = query.OrderByDescending("AuthorId"); | ||||
|             query = query.ThenBy("Id"); | ||||
| 
 | ||||
|             var first = query.First(); | ||||
|             var second = query.Skip(1).First(); | ||||
| 
 | ||||
|             Assert.IsTrue(first.Id == 3); | ||||
|             Assert.IsTrue(second.Id == 1); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -2,6 +2,7 @@ | ||||
| using PoweredSoft.DynamicLinq.Helpers; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Data.SqlClient; | ||||
| using System.Linq; | ||||
| using System.Linq.Expressions; | ||||
| using System.Text; | ||||
| @ -18,6 +19,8 @@ namespace PoweredSoft.DynamicLinq.Extensions | ||||
|             return query; | ||||
|         } | ||||
|          | ||||
|       | ||||
| 
 | ||||
|         public static IQueryable<T> Query<T> (this IQueryable<T> query, Action<QueryBuilder<T>> callback) | ||||
|         { | ||||
|             var queryBuilder = new QueryBuilder<T>(query); | ||||
| @ -25,5 +28,45 @@ namespace PoweredSoft.DynamicLinq.Extensions | ||||
|             var ret = queryBuilder.Build(); | ||||
|             return ret; | ||||
|         } | ||||
| 
 | ||||
|         public static IQueryable<T> Sort<T>(this IQueryable<T> query, string path, SortOrder sortOrder, bool appendSort) | ||||
|         { | ||||
|             var qb = new QueryBuilder<T>(query); | ||||
|             qb.Sort(path, sortOrder, appendSort); | ||||
|             var ret = qb.Build(); | ||||
|             return ret; | ||||
|         } | ||||
| 
 | ||||
|         public static IQueryable<T> OrderBy<T>(this IQueryable<T> query, string path) | ||||
|         { | ||||
|             var qb = new QueryBuilder<T>(query); | ||||
|             qb.OrderBy(path); | ||||
|             var ret = qb.Build(); | ||||
|             return ret; | ||||
|         } | ||||
| 
 | ||||
|         public static IQueryable<T> OrderByDescending<T>(this IQueryable<T> query, string path) | ||||
|         { | ||||
|             var qb = new QueryBuilder<T>(query); | ||||
|             qb.OrderByDescending(path); | ||||
|             var ret = qb.Build(); | ||||
|             return ret; | ||||
|         } | ||||
| 
 | ||||
|         public static IQueryable<T> ThenBy<T>(this IQueryable<T> query, string path) | ||||
|         { | ||||
|             var qb = new QueryBuilder<T>(query); | ||||
|             qb.ThenBy(path); | ||||
|             var ret = qb.Build(); | ||||
|             return ret; | ||||
|         } | ||||
| 
 | ||||
|         public static IQueryable<T> ThenByDescending<T>(this IQueryable<T> query, string path) | ||||
|         { | ||||
|             var qb = new QueryBuilder<T>(query); | ||||
|             qb.ThenByDescending(path); | ||||
|             var ret = qb.Build(); | ||||
|             return ret; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,6 +1,7 @@ | ||||
| using PoweredSoft.DynamicLinq.Helpers; | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Data.SqlClient; | ||||
| using System.Linq; | ||||
| using System.Linq.Expressions; | ||||
| using System.Text; | ||||
| @ -14,7 +15,9 @@ namespace PoweredSoft.DynamicLinq.Fluent | ||||
| 
 | ||||
|         public Type QueryableType { get; set; } | ||||
| 
 | ||||
|         public List<QueryBuilderFilter> Parts { get; protected set; } = new List<QueryBuilderFilter>(); | ||||
|         public List<QueryBuilderFilter> Filters { get; protected set; } = new List<QueryBuilderFilter>(); | ||||
| 
 | ||||
|         public List<QueryBuilderSort> Sorts { get; protected set; } = new List<QueryBuilderSort>(); | ||||
| 
 | ||||
|         public QueryBuilder(IQueryable<T> query) | ||||
|         { | ||||
| @ -25,7 +28,7 @@ namespace PoweredSoft.DynamicLinq.Fluent | ||||
|             QueryConvertStrategy convertStrategy = QueryConvertStrategy.ConvertConstantToComparedPropertyOrField,  | ||||
|             bool and = true) | ||||
|         { | ||||
|             Parts.Add(new QueryBuilderFilter | ||||
|             Filters.Add(new QueryBuilderFilter | ||||
|             { | ||||
|                 And = and, | ||||
|                 ConditionOperator = conditionOperators, | ||||
| @ -37,6 +40,17 @@ namespace PoweredSoft.DynamicLinq.Fluent | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         public virtual QueryBuilder<T> Sort(string path, SortOrder sortOrder, bool appendSort) | ||||
|         { | ||||
|             Sorts.Add(new QueryBuilderSort | ||||
|             { | ||||
|                 Path = path, | ||||
|                 SortOrder = sortOrder, | ||||
|                 AppendSort = appendSort | ||||
|             }); | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         public virtual QueryBuilder<T> SubQuery(Action<QueryBuilder<T>> subQuery, bool and = true) | ||||
|         { | ||||
|             // create query builder for same type. | ||||
| @ -48,8 +62,8 @@ namespace PoweredSoft.DynamicLinq.Fluent | ||||
|             // create a query part. | ||||
|             var part = new QueryBuilderFilter(); | ||||
|             part.And = and; | ||||
|             part.Parts = qb.Parts; | ||||
|             Parts.Add(part); | ||||
|             part.Parts = qb.Filters; | ||||
|             Filters.Add(part); | ||||
|              | ||||
|             //return self. | ||||
|             return this; | ||||
| @ -72,17 +86,78 @@ namespace PoweredSoft.DynamicLinq.Fluent | ||||
|             // the query. | ||||
|             var query = Query; | ||||
| 
 | ||||
|             // execute the filters. | ||||
|             // build the filters. | ||||
|             query = BuildFilters(query); | ||||
| 
 | ||||
|             // build the sorts | ||||
|             query = BuildSorts(query); | ||||
|              | ||||
|             return query; | ||||
|         } | ||||
| 
 | ||||
|         public virtual QueryBuilder<T> OrderBy(string path) | ||||
|         { | ||||
|             Sorts.Clear(); | ||||
|             Sorts.Add(new QueryBuilderSort | ||||
|             { | ||||
|                 Path = path, | ||||
|                 SortOrder = SortOrder.Ascending, | ||||
|                 AppendSort = false | ||||
|             }); | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         public virtual QueryBuilder<T> OrderByDescending(string path) | ||||
|         { | ||||
|             Sorts.Clear(); | ||||
|             Sorts.Add(new QueryBuilderSort | ||||
|             { | ||||
|                 Path = path, | ||||
|                 SortOrder = SortOrder.Descending, | ||||
|                 AppendSort = false | ||||
|             }); | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         public virtual QueryBuilder<T> ThenBy(string path) | ||||
|         { | ||||
|             Sorts.Add(new QueryBuilderSort | ||||
|             { | ||||
|                 Path = path, | ||||
|                 SortOrder = SortOrder.Ascending, | ||||
|                 AppendSort = true | ||||
|             }); | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         public virtual QueryBuilder<T> ThenByDescending(string path) | ||||
|         { | ||||
|             Sorts.Add(new QueryBuilderSort | ||||
|             { | ||||
|                 Path = path, | ||||
|                 SortOrder = SortOrder.Descending, | ||||
|                 AppendSort = true | ||||
|             }); | ||||
|             return this; | ||||
|         } | ||||
| 
 | ||||
|         protected virtual IQueryable<T> BuildSorts(IQueryable<T> query) | ||||
|         { | ||||
|             Sorts.ForEach(sort => | ||||
|             { | ||||
|                 query = QueryableHelpers.CreateSortExpression(query, sort.Path, sort.SortOrder, sort.AppendSort); | ||||
|             }); | ||||
| 
 | ||||
|             return query; | ||||
|         } | ||||
| 
 | ||||
|         protected virtual IQueryable<T> BuildFilters(IQueryable<T> query) | ||||
|         { | ||||
|             if (Filters == null || Filters?.Count() == 0) | ||||
|                 return query;               | ||||
| 
 | ||||
|             var parameter = Expression.Parameter(typeof(T), "t"); | ||||
|             var expression = BuildFilterExpression(parameter, Parts); | ||||
|             var expression = BuildFilterExpression(parameter, Filters); | ||||
|             var lambda = Expression.Lambda<Func<T, bool>>(expression, parameter); | ||||
|             query = query.Where(lambda); | ||||
|             return query; | ||||
|  | ||||
							
								
								
									
										18
									
								
								PoweredSoft.DynamicLinq/Fluent/QueryBuilderSort.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								PoweredSoft.DynamicLinq/Fluent/QueryBuilderSort.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,18 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Data.SqlClient; | ||||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Threading.Tasks; | ||||
| 
 | ||||
| namespace PoweredSoft.DynamicLinq.Fluent | ||||
| { | ||||
|     public class QueryBuilderSort | ||||
|     { | ||||
|         public string Path { get; set; } | ||||
| 
 | ||||
|         public SortOrder SortOrder { get; set; } = SortOrder.Ascending; | ||||
| 
 | ||||
|         public bool AppendSort { get; set; } | ||||
|     } | ||||
| } | ||||
| @ -1,5 +1,6 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Data.SqlClient; | ||||
| using System.Linq; | ||||
| using System.Linq.Expressions; | ||||
| using System.Text; | ||||
| @ -91,5 +92,30 @@ namespace PoweredSoft.DynamicLinq.Helpers | ||||
| 
 | ||||
|             throw new NotSupportedException($"{convertStrategy} supplied is not recognized"); | ||||
|         } | ||||
| 
 | ||||
|         public static IQueryable<T> CreateSortExpression<T>(IQueryable<T> query, string sortPath, SortOrder sortOrder, bool appendSort = true) | ||||
|         { | ||||
|             var parameter = Expression.Parameter(typeof(T), "t"); | ||||
|             var member = QueryableHelpers.ResolvePathForExpression(parameter, sortPath); | ||||
| 
 | ||||
|             string sortCommand = null; | ||||
|             if (sortOrder == SortOrder.Descending) | ||||
|                 sortCommand = appendSort == false ? "OrderByDescending" : "ThenByDescending"; | ||||
|             else | ||||
|                 sortCommand = appendSort == false ? "OrderBy" : "ThenBy"; | ||||
| 
 | ||||
|             var expression = Expression.Lambda(member, parameter); | ||||
| 
 | ||||
|             var resultExpression = Expression.Call | ||||
|                     (typeof(Queryable), | ||||
|                     sortCommand, | ||||
|                     new Type[] { typeof(T), member.Type }, | ||||
|                     query.Expression, | ||||
|                     Expression.Quote(expression) | ||||
|                 ); | ||||
| 
 | ||||
|             query = query.Provider.CreateQuery<T>(resultExpression); | ||||
|             return query; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -42,6 +42,7 @@ | ||||
|   <ItemGroup> | ||||
|     <Compile Include="Constants.cs" /> | ||||
|     <Compile Include="Extensions\QueryableExtensions.cs" /> | ||||
|     <Compile Include="Fluent\QueryBuilderSort.cs" /> | ||||
|     <Compile Include="Helpers\QueryableHelpers.cs" /> | ||||
|     <Compile Include="Helpers\TypeHelpers.cs" /> | ||||
|     <Compile Include="Properties\AssemblyInfo.cs" /> | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user