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
|
||||
{
|
||||
IQueryable<TEntity> ApplyAll<TEntity>(ISieveModel model, IQueryable<TEntity> source, object[] dataForCustomMethods = null);
|
||||
IQueryable<TEntity> ApplySorting<TEntity>(ISieveModel model, IQueryable<TEntity> result, object[] dataForCustomMethods = null);
|
||||
IQueryable<TEntity> ApplyFiltering<TEntity>(ISieveModel model, IQueryable<TEntity> result, 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, SieveProperty<TEntity>[] sieveProperties = null, 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);
|
||||
}
|
||||
}
|
@ -19,7 +19,6 @@ namespace Sieve.Services
|
||||
private IOptions<SieveOptions> _options;
|
||||
private ISieveCustomSortMethods _customSortMethods;
|
||||
private ISieveCustomFilterMethods _customFilterMethods;
|
||||
|
||||
|
||||
public SieveProcessor(IOptions<SieveOptions> options,
|
||||
ISieveCustomSortMethods customSortMethods,
|
||||
@ -49,7 +48,11 @@ namespace Sieve.Services
|
||||
_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;
|
||||
|
||||
@ -57,10 +60,10 @@ namespace Sieve.Services
|
||||
return result;
|
||||
|
||||
// Filter
|
||||
result = ApplyFiltering(model, result, dataForCustomMethods);
|
||||
result = ApplyFiltering(model, result, sieveProperties, dataForCustomMethods);
|
||||
|
||||
// Sort
|
||||
result = ApplySorting(model, result, dataForCustomMethods);
|
||||
result = ApplySorting(model, result, sieveProperties, dataForCustomMethods);
|
||||
|
||||
// Paginate
|
||||
result = ApplyPagination(model, result);
|
||||
@ -68,7 +71,11 @@ namespace Sieve.Services
|
||||
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)
|
||||
return result;
|
||||
@ -76,7 +83,8 @@ namespace Sieve.Services
|
||||
var useThenBy = false;
|
||||
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)
|
||||
{
|
||||
@ -97,15 +105,20 @@ namespace Sieve.Services
|
||||
|
||||
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)
|
||||
return result;
|
||||
|
||||
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)
|
||||
{
|
||||
@ -188,7 +201,7 @@ namespace Sieve.Services
|
||||
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 =>
|
||||
{
|
||||
|
@ -33,6 +33,24 @@ namespace SieveTests.Controllers
|
||||
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]
|
||||
public JsonResult Create(int number = 10)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user