mirror of
https://github.com/Biarity/Sieve.git
synced 2024-11-22 21:42:38 +01:00
Extended SieveProcessor to optionally accept a list of SieveProperties.
This commit is contained in:
parent
aa6a836cfb
commit
c9014a913c
12
Sieve/Models/Allow.cs
Normal file
12
Sieve/Models/Allow.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace Sieve.Models
|
||||||
|
{
|
||||||
|
[Flags]
|
||||||
|
public enum Allow
|
||||||
|
{
|
||||||
|
Sort = 1,
|
||||||
|
Filter = 2,
|
||||||
|
SortAndFilter = 4
|
||||||
|
}
|
||||||
|
}
|
43
Sieve/Models/SieveProperty.cs
Normal file
43
Sieve/Models/SieveProperty.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
using System;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Reflection;
|
||||||
|
|
||||||
|
namespace Sieve.Models
|
||||||
|
{
|
||||||
|
public class SieveProperty<TEntity>
|
||||||
|
{
|
||||||
|
public static SieveProperty<TEntity> For(Expression<Func<TEntity, object>> expression, Allow allow, string nameInQuery = null)
|
||||||
|
{
|
||||||
|
var propertyInfo = GetPropertyInfo(expression);
|
||||||
|
|
||||||
|
if (nameInQuery == null)
|
||||||
|
nameInQuery = propertyInfo.Name;
|
||||||
|
|
||||||
|
return new SieveProperty<TEntity>(propertyInfo, nameInQuery, allow.HasFlag(Allow.Sort), allow.HasFlag(Allow.Filter));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PropertyInfo GetPropertyInfo(Expression<Func<TEntity, object>> exp)
|
||||||
|
{
|
||||||
|
if (!(exp.Body is MemberExpression body))
|
||||||
|
{
|
||||||
|
var ubody = (UnaryExpression) exp.Body;
|
||||||
|
body = ubody.Operand as MemberExpression;
|
||||||
|
}
|
||||||
|
|
||||||
|
return body?.Member as PropertyInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PropertyInfo PropertyInfo { get; }
|
||||||
|
public string NameInQuery { get; }
|
||||||
|
public bool CanSort { get; }
|
||||||
|
public bool CanFilter { get; }
|
||||||
|
|
||||||
|
public SieveProperty(PropertyInfo propertyInfo, string nameInQuery, bool canSort, bool canFilter)
|
||||||
|
{
|
||||||
|
PropertyInfo = propertyInfo;
|
||||||
|
NameInQuery = nameInQuery;
|
||||||
|
CanSort = canSort;
|
||||||
|
CanFilter = canFilter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,9 +6,9 @@ namespace Sieve.Services
|
|||||||
{
|
{
|
||||||
public interface ISieveProcessor
|
public interface ISieveProcessor
|
||||||
{
|
{
|
||||||
IQueryable<TEntity> ApplyAll<TEntity>(ISieveModel model, IQueryable<TEntity> source, object[] dataForCustomMethods = null);
|
IQueryable<TEntity> ApplyAll<TEntity>(ISieveModel model, IQueryable<TEntity> source, SieveProperty<TEntity>[] sieveProperties = null, object[] dataForCustomMethods = null);
|
||||||
IQueryable<TEntity> ApplySorting<TEntity>(ISieveModel model, IQueryable<TEntity> result, object[] dataForCustomMethods = null);
|
IQueryable<TEntity> ApplySorting<TEntity>(ISieveModel model, IQueryable<TEntity> result, SieveProperty<TEntity>[] sieveProperties = null, object[] dataForCustomMethods = null);
|
||||||
IQueryable<TEntity> ApplyFiltering<TEntity>(ISieveModel model, IQueryable<TEntity> result, object[] dataForCustomMethods = null);
|
IQueryable<TEntity> ApplyFiltering<TEntity>(ISieveModel model, IQueryable<TEntity> result, SieveProperty<TEntity>[] sieveProperties = null, object[] dataForCustomMethods = null);
|
||||||
IQueryable<TEntity> ApplyPagination<TEntity>(ISieveModel model, IQueryable<TEntity> result);
|
IQueryable<TEntity> ApplyPagination<TEntity>(ISieveModel model, IQueryable<TEntity> result);
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -20,7 +20,6 @@ namespace Sieve.Services
|
|||||||
private ISieveCustomSortMethods _customSortMethods;
|
private ISieveCustomSortMethods _customSortMethods;
|
||||||
private ISieveCustomFilterMethods _customFilterMethods;
|
private ISieveCustomFilterMethods _customFilterMethods;
|
||||||
|
|
||||||
|
|
||||||
public SieveProcessor(IOptions<SieveOptions> options,
|
public SieveProcessor(IOptions<SieveOptions> options,
|
||||||
ISieveCustomSortMethods customSortMethods,
|
ISieveCustomSortMethods customSortMethods,
|
||||||
ISieveCustomFilterMethods customFilterMethods)
|
ISieveCustomFilterMethods customFilterMethods)
|
||||||
@ -49,7 +48,11 @@ namespace Sieve.Services
|
|||||||
_options = options;
|
_options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IQueryable<TEntity> ApplyAll<TEntity>(ISieveModel model, IQueryable<TEntity> source, object[] dataForCustomMethods = null)
|
public IQueryable<TEntity> ApplyAll<TEntity>(
|
||||||
|
ISieveModel model,
|
||||||
|
IQueryable<TEntity> source,
|
||||||
|
SieveProperty<TEntity>[] sieveProperties = null,
|
||||||
|
object[] dataForCustomMethods = null)
|
||||||
{
|
{
|
||||||
var result = source;
|
var result = source;
|
||||||
|
|
||||||
@ -57,10 +60,10 @@ namespace Sieve.Services
|
|||||||
return result;
|
return result;
|
||||||
|
|
||||||
// Filter
|
// Filter
|
||||||
result = ApplyFiltering(model, result, dataForCustomMethods);
|
result = ApplyFiltering(model, result, sieveProperties, dataForCustomMethods);
|
||||||
|
|
||||||
// Sort
|
// Sort
|
||||||
result = ApplySorting(model, result, dataForCustomMethods);
|
result = ApplySorting(model, result, sieveProperties, dataForCustomMethods);
|
||||||
|
|
||||||
// Paginate
|
// Paginate
|
||||||
result = ApplyPagination(model, result);
|
result = ApplyPagination(model, result);
|
||||||
@ -68,7 +71,11 @@ namespace Sieve.Services
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IQueryable<TEntity> ApplySorting<TEntity>(ISieveModel model, IQueryable<TEntity> result, object[] dataForCustomMethods = null)
|
public IQueryable<TEntity> ApplySorting<TEntity>(
|
||||||
|
ISieveModel model,
|
||||||
|
IQueryable<TEntity> result,
|
||||||
|
SieveProperty<TEntity>[] sieveProperties = null,
|
||||||
|
object[] dataForCustomMethods = null)
|
||||||
{
|
{
|
||||||
if (model?.SortsParsed == null)
|
if (model?.SortsParsed == null)
|
||||||
return result;
|
return result;
|
||||||
@ -76,7 +83,8 @@ namespace Sieve.Services
|
|||||||
var useThenBy = false;
|
var useThenBy = false;
|
||||||
foreach (var sortTerm in model.SortsParsed)
|
foreach (var sortTerm in model.SortsParsed)
|
||||||
{
|
{
|
||||||
var property = GetSieveProperty<TEntity>(true, false, sortTerm.Name);
|
var property = sieveProperties?.FirstOrDefault(_ => _.NameInQuery == sortTerm.Name && _.CanSort)?.PropertyInfo
|
||||||
|
?? GetSievePropertyViaAttribute<TEntity>(true, false, sortTerm.Name);
|
||||||
|
|
||||||
if (property != null)
|
if (property != null)
|
||||||
{
|
{
|
||||||
@ -98,14 +106,19 @@ namespace Sieve.Services
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IQueryable<TEntity> ApplyFiltering<TEntity>(ISieveModel model, IQueryable<TEntity> result, object[] dataForCustomMethods = null)
|
public IQueryable<TEntity> ApplyFiltering<TEntity>(
|
||||||
|
ISieveModel model,
|
||||||
|
IQueryable<TEntity> result,
|
||||||
|
SieveProperty<TEntity>[] sieveProperties = null,
|
||||||
|
object[] dataForCustomMethods = null)
|
||||||
{
|
{
|
||||||
if (model?.FiltersParsed == null)
|
if (model?.FiltersParsed == null)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
foreach (var filterTerm in model.FiltersParsed)
|
foreach (var filterTerm in model.FiltersParsed)
|
||||||
{
|
{
|
||||||
var property = GetSieveProperty<TEntity>(false, true, filterTerm.Name);
|
var property = sieveProperties?.FirstOrDefault(_ => _.NameInQuery == filterTerm.Name && _.CanFilter)?.PropertyInfo
|
||||||
|
?? GetSievePropertyViaAttribute<TEntity>(false, true, filterTerm.Name);
|
||||||
|
|
||||||
if (property != null)
|
if (property != null)
|
||||||
{
|
{
|
||||||
@ -188,7 +201,7 @@ namespace Sieve.Services
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PropertyInfo GetSieveProperty<TEntity>(bool canSortRequired, bool canFilterRequired, string name)
|
private PropertyInfo GetSievePropertyViaAttribute<TEntity>(bool canSortRequired, bool canFilterRequired, string name)
|
||||||
{
|
{
|
||||||
return typeof(TEntity).GetProperties().FirstOrDefault(p =>
|
return typeof(TEntity).GetProperties().FirstOrDefault(p =>
|
||||||
{
|
{
|
||||||
|
@ -33,6 +33,24 @@ namespace SieveTests.Controllers
|
|||||||
return Json(result.ToList());
|
return Json(result.ToList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[HttpGet]
|
||||||
|
public JsonResult GetAllWithSieveAndPropertyMapping(SieveModel sieveModel)
|
||||||
|
{
|
||||||
|
var result = _dbContext.Posts.AsNoTracking();
|
||||||
|
|
||||||
|
var sieveProperties = new[]
|
||||||
|
{
|
||||||
|
SieveProperty<Post>.For(_ => _.Title, Allow.Filter, "name"),
|
||||||
|
SieveProperty<Post>.For(_ => _.CommentCount, Allow.SortAndFilter),
|
||||||
|
SieveProperty<Post>.For(_ => _.LikeCount, Allow.Sort),
|
||||||
|
SieveProperty<Post>.For(_ => _.DateCreated, Allow.SortAndFilter),
|
||||||
|
};
|
||||||
|
|
||||||
|
result = _sieveProcessor.ApplyAll(sieveModel, result, sieveProperties);
|
||||||
|
|
||||||
|
return Json(result.ToList());
|
||||||
|
}
|
||||||
|
|
||||||
[HttpGet]
|
[HttpGet]
|
||||||
public JsonResult Create(int number = 10)
|
public JsonResult Create(int number = 10)
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user