order by is refactored to not force generics anymore.

This commit is contained in:
David Lebée 2018-03-14 18:50:43 -05:00
parent d6265c3b8d
commit c4a398a8cb
8 changed files with 75 additions and 109 deletions

View File

@ -82,14 +82,14 @@ namespace PoweredSoft.DynamicLinq.Test
// the query. // the query.
var query = posts.AsQueryable(); var query = posts.AsQueryable();
var queryBuilder = new PoweredSoft.DynamicLinq.Fluent.OrderByBuilder<Post>(query); var queryBuilder = new OrderByBuilder(query);
// add some sorting. // add some sorting.
queryBuilder queryBuilder
.OrderByDescending("AuthorId") .OrderByDescending("AuthorId")
.ThenBy("Id"); .ThenBy("Id");
query = queryBuilder.Build(); query = queryBuilder.Build().Cast<Post>();
var first = query.First(); var first = query.First();
var second = query.Skip(1).First(); var second = query.Skip(1).First();

View File

@ -35,7 +35,7 @@ namespace PoweredSoft.DynamicLinq
All All
} }
public enum QuerySortDirection public enum QueryOrderByDirection
{ {
Ascending, Ascending,
Descending Descending

View File

@ -20,8 +20,8 @@ namespace PoweredSoft.DynamicLinq
public static IEnumerable<T> Query<T>(this IEnumerable<T> list, Action<WhereBuilder<T>> callback) public static IEnumerable<T> Query<T>(this IEnumerable<T> list, Action<WhereBuilder<T>> callback)
=> list.AsQueryable().Query(callback); => list.AsQueryable().Query(callback);
public static IEnumerable<T> Sort<T>(this IEnumerable<T> list, string path, QuerySortDirection sortDirection, bool appendSort) public static IEnumerable<T> Sort<T>(this IEnumerable<T> list, string path, QueryOrderByDirection sortDirection, bool appendSort)
=> list.AsQueryable().Sort(path, sortDirection, appendSort); => list.AsQueryable().OrderBy(path, sortDirection, appendSort);
public static IEnumerable<T> OrderBy<T>(this IEnumerable<T> list, string path) public static IEnumerable<T> OrderBy<T>(this IEnumerable<T> list, string path)
=> list.AsQueryable().OrderBy(path); => list.AsQueryable().OrderBy(path);

View File

@ -30,46 +30,48 @@ namespace PoweredSoft.DynamicLinq
return ret; return ret;
} }
public static IQueryable<T> Sort<T>(this IQueryable<T> query, string path, QuerySortDirection sortDirection, bool appendSort) // generic.
public static IQueryable<T> OrderBy<T>(this IQueryable<T> query, string path, QueryOrderByDirection direction, bool append)
{ {
var qb = new OrderByBuilder<T>(query); IQueryable queryable = query;
qb.Sort(path, sortDirection, appendSort); query = queryable.OrderBy(path, direction, append) as IQueryable<T>;
var ret = qb.Build(); return query;
return ret;
} }
public static IQueryable<T> OrderBy<T>(this IQueryable<T> query, string path) public static IQueryable<T> OrderBy<T>(this IQueryable<T> query, string path)
{ => query.OrderBy(path, QueryOrderByDirection.Ascending, false);
var qb = new OrderByBuilder<T>(query);
qb.OrderBy(path);
var ret = qb.Build();
return ret;
}
public static IQueryable<T> OrderByDescending<T>(this IQueryable<T> query, string path) public static IQueryable<T> OrderByDescending<T>(this IQueryable<T> query, string path)
{ => query.OrderBy(path, QueryOrderByDirection.Descending, false);
var qb = new OrderByBuilder<T>(query);
qb.OrderByDescending(path);
var ret = qb.Build();
return ret;
}
public static IQueryable<T> ThenBy<T>(this IQueryable<T> query, string path) public static IQueryable<T> ThenBy<T>(this IQueryable<T> query, string path)
{ => query.OrderBy(path, QueryOrderByDirection.Ascending, true);
var qb = new OrderByBuilder<T>(query);
qb.ThenBy(path);
var ret = qb.Build();
return ret;
}
public static IQueryable<T> ThenByDescending<T>(this IQueryable<T> query, string path) public static IQueryable<T> ThenByDescending<T>(this IQueryable<T> query, string path)
=> query.OrderBy(path, QueryOrderByDirection.Descending, true);
// non generic.
public static IQueryable OrderBy(this IQueryable query, string path, QueryOrderByDirection direction, bool append)
{ {
var qb = new OrderByBuilder<T>(query); var qb = new OrderByBuilder(query);
qb.ThenByDescending(path); qb.OrderBy(path, direction, append);
var ret = qb.Build(); var ret = qb.Build();
return ret; return ret;
} }
public static IQueryable OrderBy(this IQueryable query, string path)
=> query.OrderBy(path, QueryOrderByDirection.Ascending, false);
public static IQueryable OrderByDescending(this IQueryable query, string path)
=> query.OrderBy(path, QueryOrderByDirection.Descending, false);
public static IQueryable ThenBy(this IQueryable query, string path)
=> query.OrderBy(path, QueryOrderByDirection.Ascending, true);
public static IQueryable ThenByDescending(this IQueryable query, string path)
=> query.OrderBy(path, QueryOrderByDirection.Descending, true);
// group by
public static IQueryable GroupBy<T>(this IQueryable<T> query, string path) public static IQueryable GroupBy<T>(this IQueryable<T> query, string path)
=> QueryableHelpers.GroupBy(query, typeof(T), path); => QueryableHelpers.GroupBy(query, typeof(T), path);

View File

@ -1,30 +1,60 @@
using PoweredSoft.DynamicLinq.Helpers; using PoweredSoft.DynamicLinq.Helpers;
using System; using System;
using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
namespace PoweredSoft.DynamicLinq.Fluent namespace PoweredSoft.DynamicLinq.Fluent
{ {
public class OrderByBuilder
public class OrderByBuilder<T> : OrderByBuilderBase
{ {
public IQueryable<T> Query { get; } public IQueryable Query { get; }
public OrderByBuilder(IQueryable<T> query) public OrderByBuilder(IQueryable query)
{ {
Query = query; Query = query;
} }
public virtual IQueryable<T> Build() public virtual IQueryable Build()
{ {
var query = Query; var query = Query;
Sorts.ForEach(sort => Sorts.ForEach(sort =>
{ {
query = QueryableHelpers.CreateOrderByExpression(query, sort.Path, sort.sortDirection, sort.AppendSort); query = QueryableHelpers.CreateOrderByExpression(query, sort.Path, sort.Direction, sort.Append);
}); });
return query; return query;
} }
public List<OrderByPart> Sorts { get; protected set; } = new List<OrderByPart>();
public virtual OrderByBuilder OrderBy(string path, QueryOrderByDirection direction, bool append)
{
if (append == false)
Sorts.Clear();
Sorts.Add(new OrderByPart
{
Path = path,
Direction = direction,
Append = append
});
return this;
}
#region shortcuts
public virtual OrderByBuilder OrderBy(string path)
=> OrderBy(path, QueryOrderByDirection.Ascending, false);
public virtual OrderByBuilder OrderByDescending(string path)
=> OrderBy(path, QueryOrderByDirection.Descending, false);
public virtual OrderByBuilder ThenBy(string path)
=> OrderBy(path, QueryOrderByDirection.Ascending, true);
public virtual OrderByBuilder ThenByDescending(string path)
=> OrderBy(path, QueryOrderByDirection.Descending, true);
#endregion
} }
} }

View File

@ -1,66 +0,0 @@
using System.Collections.Generic;
namespace PoweredSoft.DynamicLinq.Fluent
{
public class OrderByBuilderBase
{
public List<OrderByPart> Sorts { get; protected set; } = new List<OrderByPart>();
public virtual OrderByBuilderBase Sort(string path, QuerySortDirection sortDirection, bool appendSort)
{
Sorts.Add(new OrderByPart
{
Path = path,
sortDirection = sortDirection,
AppendSort = appendSort
});
return this;
}
public virtual OrderByBuilderBase OrderBy(string path)
{
Sorts.Clear();
Sorts.Add(new OrderByPart
{
Path = path,
sortDirection = QuerySortDirection.Ascending,
AppendSort = false
});
return this;
}
public virtual OrderByBuilderBase OrderByDescending(string path)
{
Sorts.Clear();
Sorts.Add(new OrderByPart
{
Path = path,
sortDirection = QuerySortDirection.Descending,
AppendSort = false
});
return this;
}
public virtual OrderByBuilderBase ThenBy(string path)
{
Sorts.Add(new OrderByPart
{
Path = path,
sortDirection = QuerySortDirection.Ascending,
AppendSort = true
});
return this;
}
public virtual OrderByBuilderBase ThenByDescending(string path)
{
Sorts.Add(new OrderByPart
{
Path = path,
sortDirection = QuerySortDirection.Descending,
AppendSort = true
});
return this;
}
}
}

View File

@ -10,8 +10,8 @@ namespace PoweredSoft.DynamicLinq.Fluent
{ {
public string Path { get; set; } public string Path { get; set; }
public QuerySortDirection sortDirection { get; set; } = QuerySortDirection.Ascending; public QueryOrderByDirection Direction { get; set; } = QueryOrderByDirection.Ascending;
public bool AppendSort { get; set; } public bool Append { get; set; }
} }
} }

View File

@ -270,13 +270,13 @@ namespace PoweredSoft.DynamicLinq.Helpers
throw new NotSupportedException($"{convertStrategy} supplied is not recognized"); throw new NotSupportedException($"{convertStrategy} supplied is not recognized");
} }
public static IQueryable<T> CreateOrderByExpression<T>(IQueryable<T> query, string sortPath, QuerySortDirection sortDirection, bool appendSort = true) public static IQueryable CreateOrderByExpression(IQueryable query, string sortPath, QueryOrderByDirection sortDirection, bool appendSort = true)
{ {
var parameter = Expression.Parameter(typeof(T), "t"); var parameter = Expression.Parameter(query.ElementType, "t");
var member = QueryableHelpers.ResolvePathForExpression(parameter, sortPath); var member = QueryableHelpers.ResolvePathForExpression(parameter, sortPath);
string sortCommand = null; string sortCommand = null;
if (sortDirection == QuerySortDirection.Descending) if (sortDirection == QueryOrderByDirection.Descending)
sortCommand = appendSort == false ? "OrderByDescending" : "ThenByDescending"; sortCommand = appendSort == false ? "OrderByDescending" : "ThenByDescending";
else else
sortCommand = appendSort == false ? "OrderBy" : "ThenBy"; sortCommand = appendSort == false ? "OrderBy" : "ThenBy";
@ -286,12 +286,12 @@ namespace PoweredSoft.DynamicLinq.Helpers
var resultExpression = Expression.Call var resultExpression = Expression.Call
(typeof(Queryable), (typeof(Queryable),
sortCommand, sortCommand,
new Type[] { typeof(T), member.Type }, new Type[] { query.ElementType, member.Type },
query.Expression, query.Expression,
Expression.Quote(expression) Expression.Quote(expression)
); );
query = query.Provider.CreateQuery<T>(resultExpression); query = query.Provider.CreateQuery(resultExpression);
return query; return query;
} }