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.
var query = posts.AsQueryable();
var queryBuilder = new PoweredSoft.DynamicLinq.Fluent.OrderByBuilder<Post>(query);
var queryBuilder = new OrderByBuilder(query);
// add some sorting.
queryBuilder
.OrderByDescending("AuthorId")
.ThenBy("Id");
query = queryBuilder.Build();
query = queryBuilder.Build().Cast<Post>();
var first = query.First();
var second = query.Skip(1).First();

View File

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

View File

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

View File

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

View File

@ -1,30 +1,60 @@
using PoweredSoft.DynamicLinq.Helpers;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace PoweredSoft.DynamicLinq.Fluent
{
public class OrderByBuilder<T> : OrderByBuilderBase
public class OrderByBuilder
{
public IQueryable<T> Query { get; }
public IQueryable Query { get; }
public OrderByBuilder(IQueryable<T> query)
public OrderByBuilder(IQueryable query)
{
Query = query;
}
public virtual IQueryable<T> Build()
public virtual IQueryable Build()
{
var query = Query;
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;
}
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 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");
}
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);
string sortCommand = null;
if (sortDirection == QuerySortDirection.Descending)
if (sortDirection == QueryOrderByDirection.Descending)
sortCommand = appendSort == false ? "OrderByDescending" : "ThenByDescending";
else
sortCommand = appendSort == false ? "OrderBy" : "ThenBy";
@ -286,12 +286,12 @@ namespace PoweredSoft.DynamicLinq.Helpers
var resultExpression = Expression.Call
(typeof(Queryable),
sortCommand,
new Type[] { typeof(T), member.Type },
new Type[] { query.ElementType, member.Type },
query.Expression,
Expression.Quote(expression)
);
query = query.Provider.CreateQuery<T>(resultExpression);
query = query.Provider.CreateQuery(resultExpression);
return query;
}