mirror of
https://github.com/Biarity/Sieve.git
synced 2024-11-22 13:32:33 +01:00
SievePropertyMapper for #4
This commit is contained in:
parent
b52362e2bc
commit
0bd38b8348
@ -1,11 +1,12 @@
|
|||||||
using System;
|
using Sieve.Models;
|
||||||
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace Sieve.Attributes
|
namespace Sieve.Attributes
|
||||||
{
|
{
|
||||||
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
|
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
|
||||||
public class SieveAttribute : Attribute
|
public class SieveAttribute : Attribute, ISievePropertyMetadata
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Override name used
|
/// Override name used
|
||||||
|
14
Sieve/Models/ISievePropertyMetadata.cs
Normal file
14
Sieve/Models/ISievePropertyMetadata.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Sieve.Models
|
||||||
|
{
|
||||||
|
public interface ISievePropertyMetadata
|
||||||
|
{
|
||||||
|
string Name { get; set; }
|
||||||
|
bool CanFilter { get; set; }
|
||||||
|
bool CanSort { get; set; }
|
||||||
|
}
|
||||||
|
}
|
14
Sieve/Models/SievePropertyMetadata.cs
Normal file
14
Sieve/Models/SievePropertyMetadata.cs
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Sieve.Models
|
||||||
|
{
|
||||||
|
public class SievePropertyMetadata : ISievePropertyMetadata
|
||||||
|
{
|
||||||
|
public string Name { get; set; }
|
||||||
|
public bool CanFilter { get; set; }
|
||||||
|
public bool CanSort { get; set; }
|
||||||
|
}
|
||||||
|
}
|
@ -19,12 +19,14 @@ namespace Sieve.Services
|
|||||||
private IOptions<SieveOptions> _options;
|
private IOptions<SieveOptions> _options;
|
||||||
private ISieveCustomSortMethods _customSortMethods;
|
private ISieveCustomSortMethods _customSortMethods;
|
||||||
private ISieveCustomFilterMethods _customFilterMethods;
|
private ISieveCustomFilterMethods _customFilterMethods;
|
||||||
|
private SievePropertyMapper mapper = new SievePropertyMapper();
|
||||||
|
|
||||||
|
|
||||||
public SieveProcessor(IOptions<SieveOptions> options,
|
public SieveProcessor(IOptions<SieveOptions> options,
|
||||||
ISieveCustomSortMethods customSortMethods,
|
ISieveCustomSortMethods customSortMethods,
|
||||||
ISieveCustomFilterMethods customFilterMethods)
|
ISieveCustomFilterMethods customFilterMethods)
|
||||||
{
|
{
|
||||||
|
mapper = MapProperties(mapper);
|
||||||
_options = options;
|
_options = options;
|
||||||
_customSortMethods = customSortMethods;
|
_customSortMethods = customSortMethods;
|
||||||
_customFilterMethods = customFilterMethods;
|
_customFilterMethods = customFilterMethods;
|
||||||
@ -33,6 +35,7 @@ namespace Sieve.Services
|
|||||||
public SieveProcessor(IOptions<SieveOptions> options,
|
public SieveProcessor(IOptions<SieveOptions> options,
|
||||||
ISieveCustomSortMethods customSortMethods)
|
ISieveCustomSortMethods customSortMethods)
|
||||||
{
|
{
|
||||||
|
mapper = MapProperties(mapper);
|
||||||
_options = options;
|
_options = options;
|
||||||
_customSortMethods = customSortMethods;
|
_customSortMethods = customSortMethods;
|
||||||
}
|
}
|
||||||
@ -40,12 +43,14 @@ namespace Sieve.Services
|
|||||||
public SieveProcessor(IOptions<SieveOptions> options,
|
public SieveProcessor(IOptions<SieveOptions> options,
|
||||||
ISieveCustomFilterMethods customFilterMethods)
|
ISieveCustomFilterMethods customFilterMethods)
|
||||||
{
|
{
|
||||||
|
mapper = MapProperties(mapper);
|
||||||
_options = options;
|
_options = options;
|
||||||
_customFilterMethods = customFilterMethods;
|
_customFilterMethods = customFilterMethods;
|
||||||
}
|
}
|
||||||
|
|
||||||
public SieveProcessor(IOptions<SieveOptions> options)
|
public SieveProcessor(IOptions<SieveOptions> options)
|
||||||
{
|
{
|
||||||
|
mapper = MapProperties(mapper);
|
||||||
_options = options;
|
_options = options;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +62,10 @@ namespace Sieve.Services
|
|||||||
/// <param name="source">Data source</param>
|
/// <param name="source">Data source</param>
|
||||||
/// <param name="dataForCustomMethods">Additional data that will be passed down to custom methods</param>
|
/// <param name="dataForCustomMethods">Additional data that will be passed down to custom methods</param>
|
||||||
/// <returns>Returns a transformed version of `source`</returns>
|
/// <returns>Returns a transformed version of `source`</returns>
|
||||||
public IQueryable<TEntity> ApplyAll<TEntity>(ISieveModel<IFilterTerm, ISortTerm> model, IQueryable<TEntity> source, object[] dataForCustomMethods = null)
|
public IQueryable<TEntity> ApplyAll<TEntity>(
|
||||||
|
ISieveModel<IFilterTerm, ISortTerm> model,
|
||||||
|
IQueryable<TEntity> source,
|
||||||
|
object[] dataForCustomMethods = null)
|
||||||
{
|
{
|
||||||
var result = source;
|
var result = source;
|
||||||
|
|
||||||
@ -84,7 +92,10 @@ namespace Sieve.Services
|
|||||||
/// <param name="source">Data source</param>
|
/// <param name="source">Data source</param>
|
||||||
/// <param name="dataForCustomMethods">Additional data that will be passed down to custom methods</param>
|
/// <param name="dataForCustomMethods">Additional data that will be passed down to custom methods</param>
|
||||||
/// <returns>Returns a transformed version of `source`</returns>
|
/// <returns>Returns a transformed version of `source`</returns>
|
||||||
public IQueryable<TEntity> ApplyFiltering<TEntity>(ISieveModel<IFilterTerm, ISortTerm> model, IQueryable<TEntity> result, object[] dataForCustomMethods = null)
|
public IQueryable<TEntity> ApplyFiltering<TEntity>(
|
||||||
|
ISieveModel<IFilterTerm, ISortTerm> model,
|
||||||
|
IQueryable<TEntity> result,
|
||||||
|
object[] dataForCustomMethods = null)
|
||||||
{
|
{
|
||||||
if (model?.FiltersParsed == null)
|
if (model?.FiltersParsed == null)
|
||||||
return result;
|
return result;
|
||||||
@ -181,7 +192,10 @@ namespace Sieve.Services
|
|||||||
/// <param name="source">Data source</param>
|
/// <param name="source">Data source</param>
|
||||||
/// <param name="dataForCustomMethods">Additional data that will be passed down to custom methods</param>
|
/// <param name="dataForCustomMethods">Additional data that will be passed down to custom methods</param>
|
||||||
/// <returns>Returns a transformed version of `source`</returns>
|
/// <returns>Returns a transformed version of `source`</returns>
|
||||||
public IQueryable<TEntity> ApplySorting<TEntity>(ISieveModel<IFilterTerm, ISortTerm> model, IQueryable<TEntity> result, object[] dataForCustomMethods = null)
|
public IQueryable<TEntity> ApplySorting<TEntity>(
|
||||||
|
ISieveModel<IFilterTerm, ISortTerm> model,
|
||||||
|
IQueryable<TEntity> result,
|
||||||
|
object[] dataForCustomMethods = null)
|
||||||
{
|
{
|
||||||
if (model?.SortsParsed == null)
|
if (model?.SortsParsed == null)
|
||||||
return result;
|
return result;
|
||||||
@ -219,7 +233,9 @@ namespace Sieve.Services
|
|||||||
/// <param name="source">Data source</param>
|
/// <param name="source">Data source</param>
|
||||||
/// <param name="dataForCustomMethods">Additional data that will be passed down to custom methods</param>
|
/// <param name="dataForCustomMethods">Additional data that will be passed down to custom methods</param>
|
||||||
/// <returns>Returns a transformed version of `source`</returns>
|
/// <returns>Returns a transformed version of `source`</returns>
|
||||||
public IQueryable<TEntity> ApplyPagination<TEntity>(ISieveModel<IFilterTerm, ISortTerm> model, IQueryable<TEntity> result)
|
public IQueryable<TEntity> ApplyPagination<TEntity>(
|
||||||
|
ISieveModel<IFilterTerm, ISortTerm> model,
|
||||||
|
IQueryable<TEntity> result)
|
||||||
{
|
{
|
||||||
var page = model?.Page ?? 1;
|
var page = model?.Page ?? 1;
|
||||||
var pageSize = model?.PageSize ?? _options.Value.DefaultPageSize;
|
var pageSize = model?.PageSize ?? _options.Value.DefaultPageSize;
|
||||||
@ -232,7 +248,26 @@ namespace Sieve.Services
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private PropertyInfo GetSieveProperty<TEntity>(bool canSortRequired, bool canFilterRequired, string name)
|
|
||||||
|
protected virtual SievePropertyMapper MapProperties(SievePropertyMapper mapper)
|
||||||
|
{
|
||||||
|
return mapper;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PropertyInfo GetSieveProperty<TEntity>(
|
||||||
|
bool canSortRequired,
|
||||||
|
bool canFilterRequired,
|
||||||
|
string name)
|
||||||
|
{
|
||||||
|
return mapper.FindProperty<TEntity>(canSortRequired, canFilterRequired, name, _options.Value.CaseSensitive)
|
||||||
|
?? FindPropertyBySieveAttribute<TEntity>(canSortRequired, canFilterRequired, name, _options.Value.CaseSensitive);
|
||||||
|
}
|
||||||
|
|
||||||
|
private PropertyInfo FindPropertyBySieveAttribute<TEntity>(
|
||||||
|
bool canSortRequired,
|
||||||
|
bool canFilterRequired,
|
||||||
|
string name,
|
||||||
|
bool isCaseSensitive)
|
||||||
{
|
{
|
||||||
return typeof(TEntity).GetProperties().FirstOrDefault(p =>
|
return typeof(TEntity).GetProperties().FirstOrDefault(p =>
|
||||||
{
|
{
|
||||||
@ -240,7 +275,7 @@ namespace Sieve.Services
|
|||||||
if ((canSortRequired ? sieveAttribute.CanSort : true) &&
|
if ((canSortRequired ? sieveAttribute.CanSort : true) &&
|
||||||
(canFilterRequired ? sieveAttribute.CanFilter : true) &&
|
(canFilterRequired ? sieveAttribute.CanFilter : true) &&
|
||||||
((sieveAttribute.Name ?? p.Name).Equals(name,
|
((sieveAttribute.Name ?? p.Name).Equals(name,
|
||||||
_options.Value.CaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase)))
|
isCaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase)))
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
107
Sieve/Services/SievePropertyMapper.cs
Normal file
107
Sieve/Services/SievePropertyMapper.cs
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
using Sieve.Models;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Linq.Expressions;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace Sieve.Services
|
||||||
|
{
|
||||||
|
public class SievePropertyMapper
|
||||||
|
{
|
||||||
|
private Dictionary<Type, Dictionary<PropertyInfo, ISievePropertyMetadata>> _map
|
||||||
|
= new Dictionary<Type, Dictionary<PropertyInfo, ISievePropertyMetadata>>();
|
||||||
|
|
||||||
|
public PropertyFluentApi<TEntity> Property<TEntity>(Expression<Func<TEntity, object>> expression)
|
||||||
|
{
|
||||||
|
_map.TryAdd(typeof(TEntity), new Dictionary<PropertyInfo, ISievePropertyMetadata>());
|
||||||
|
return new PropertyFluentApi<TEntity>(this, expression);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class PropertyFluentApi<TEntity>
|
||||||
|
{
|
||||||
|
private SievePropertyMapper _sievePropertyMapper;
|
||||||
|
private PropertyInfo _property;
|
||||||
|
|
||||||
|
public PropertyFluentApi(SievePropertyMapper sievePropertyMapper, Expression<Func<TEntity, object>> expression)
|
||||||
|
{
|
||||||
|
_sievePropertyMapper = sievePropertyMapper;
|
||||||
|
_property = GetPropertyInfo(expression);
|
||||||
|
_name = _property.Name;
|
||||||
|
_canFilter = false;
|
||||||
|
_canSort = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
private string _name;
|
||||||
|
private bool _canFilter;
|
||||||
|
private bool _canSort;
|
||||||
|
|
||||||
|
public PropertyFluentApi<TEntity> CanFilter()
|
||||||
|
{
|
||||||
|
_canFilter = true;
|
||||||
|
UpdateMap();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PropertyFluentApi<TEntity> CanSort()
|
||||||
|
{
|
||||||
|
_canSort = true;
|
||||||
|
UpdateMap();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public PropertyFluentApi<TEntity> HasName(string name)
|
||||||
|
{
|
||||||
|
_name = name;
|
||||||
|
UpdateMap();
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateMap()
|
||||||
|
{
|
||||||
|
_sievePropertyMapper._map[typeof(TEntity)][_property] = new SievePropertyMetadata()
|
||||||
|
{
|
||||||
|
Name = _name,
|
||||||
|
CanFilter = _canFilter,
|
||||||
|
CanSort = _canSort
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
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 FindProperty<TEntity>(
|
||||||
|
bool canSortRequired,
|
||||||
|
bool canFilterRequired,
|
||||||
|
string name,
|
||||||
|
bool isCaseSensitive)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
var me = _map[typeof(TEntity)]
|
||||||
|
.FirstOrDefault(kv =>
|
||||||
|
kv.Value.Name.Equals(name, isCaseSensitive ? StringComparison.Ordinal : StringComparison.OrdinalIgnoreCase) &&
|
||||||
|
(canSortRequired ? kv.Value.CanSort : true) &&
|
||||||
|
(canFilterRequired ? kv.Value.CanFilter : true));
|
||||||
|
|
||||||
|
return me.Key;
|
||||||
|
}
|
||||||
|
catch (Exception ex) when (ex is KeyNotFoundException || ex is ArgumentNullException)
|
||||||
|
{
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
28
SieveTests/Services/ApplicationSieveProcessor.cs
Normal file
28
SieveTests/Services/ApplicationSieveProcessor.cs
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Sieve.Models;
|
||||||
|
using Sieve.Services;
|
||||||
|
using SieveTests.Entities;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SieveTests.Services
|
||||||
|
{
|
||||||
|
public class ApplicationSieveProcessor : SieveProcessor
|
||||||
|
{
|
||||||
|
public ApplicationSieveProcessor(IOptions<SieveOptions> options, ISieveCustomSortMethods customSortMethods, ISieveCustomFilterMethods customFilterMethods) : base(options, customSortMethods, customFilterMethods)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override SievePropertyMapper MapProperties(SievePropertyMapper mapper)
|
||||||
|
{
|
||||||
|
mapper.Property<Post>(p => p.Title)
|
||||||
|
.CanSort()
|
||||||
|
.CanFilter()
|
||||||
|
.HasName("CustomTitleName");
|
||||||
|
|
||||||
|
return mapper;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -37,7 +37,7 @@ namespace SieveTests
|
|||||||
|
|
||||||
services.AddScoped<ISieveCustomSortMethods, SieveCustomSortMethods>();
|
services.AddScoped<ISieveCustomSortMethods, SieveCustomSortMethods>();
|
||||||
services.AddScoped<ISieveCustomFilterMethods, SieveCustomFilterMethods>();
|
services.AddScoped<ISieveCustomFilterMethods, SieveCustomFilterMethods>();
|
||||||
services.AddScoped<ISieveProcessor, SieveProcessor>();
|
services.AddScoped<ISieveProcessor, ApplicationSieveProcessor>();
|
||||||
}
|
}
|
||||||
|
|
||||||
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
|
||||||
|
@ -21,5 +21,11 @@ namespace SieveUnitTests.Entities
|
|||||||
|
|
||||||
[Sieve(CanFilter = true, CanSort = true)]
|
[Sieve(CanFilter = true, CanSort = true)]
|
||||||
public DateTimeOffset DateCreated { get; set; } = DateTimeOffset.UtcNow;
|
public DateTimeOffset DateCreated { get; set; } = DateTimeOffset.UtcNow;
|
||||||
|
|
||||||
|
public string ThisHasNoAttribute { get; set; }
|
||||||
|
|
||||||
|
public string ThisHasNoAttributeButIsAccessible { get; set; }
|
||||||
|
|
||||||
|
public int OnlySortableViaFluentApi { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
84
SieveUnitTests/Mapper.cs
Normal file
84
SieveUnitTests/Mapper.cs
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||||
|
using Sieve.Models;
|
||||||
|
using Sieve.Services;
|
||||||
|
using SieveUnitTests.Entities;
|
||||||
|
using SieveUnitTests.Services;
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace SieveUnitTests
|
||||||
|
{
|
||||||
|
[TestClass]
|
||||||
|
public class Mapper
|
||||||
|
{
|
||||||
|
private ApplicationSieveProcessor _processor;
|
||||||
|
private IQueryable<Post> _posts;
|
||||||
|
|
||||||
|
public Mapper()
|
||||||
|
{
|
||||||
|
_processor = new ApplicationSieveProcessor(new SieveOptionsAccessor(),
|
||||||
|
new SieveCustomSortMethods(),
|
||||||
|
new SieveCustomFilterMethods());
|
||||||
|
|
||||||
|
_posts = new List<Post>
|
||||||
|
{
|
||||||
|
new Post() {
|
||||||
|
Id = 1,
|
||||||
|
ThisHasNoAttributeButIsAccessible = "A",
|
||||||
|
ThisHasNoAttribute = "A",
|
||||||
|
OnlySortableViaFluentApi = 100
|
||||||
|
},
|
||||||
|
new Post() {
|
||||||
|
Id = 2,
|
||||||
|
ThisHasNoAttributeButIsAccessible = "B",
|
||||||
|
ThisHasNoAttribute = "B",
|
||||||
|
OnlySortableViaFluentApi = 50
|
||||||
|
},
|
||||||
|
new Post() {
|
||||||
|
Id = 3,
|
||||||
|
ThisHasNoAttributeButIsAccessible = "C",
|
||||||
|
ThisHasNoAttribute = "C",
|
||||||
|
OnlySortableViaFluentApi = 0
|
||||||
|
},
|
||||||
|
}.AsQueryable();
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MapperWorks()
|
||||||
|
{
|
||||||
|
var model = new SieveModel()
|
||||||
|
{
|
||||||
|
Filters = "shortname@=A",
|
||||||
|
};
|
||||||
|
|
||||||
|
var result = _processor.ApplyAll(model, _posts);
|
||||||
|
|
||||||
|
Assert.AreEqual(result.First().ThisHasNoAttributeButIsAccessible, "A");
|
||||||
|
|
||||||
|
Assert.IsTrue(result.Count() == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[TestMethod]
|
||||||
|
public void MapperSortOnlyWorks()
|
||||||
|
{
|
||||||
|
var model = new SieveModel()
|
||||||
|
{
|
||||||
|
Filters = "OnlySortableViaFluentApi@=50",
|
||||||
|
Sorts = "OnlySortableViaFluentApi"
|
||||||
|
};
|
||||||
|
|
||||||
|
var result = _processor.ApplyAll(model, _posts);
|
||||||
|
|
||||||
|
Assert.AreEqual(result.First().Id, 3);
|
||||||
|
|
||||||
|
Assert.IsTrue(result.Count() == 3);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
//Sorts = "LikeCount",
|
||||||
|
//Page = 1,
|
||||||
|
//PageSize = 10
|
||||||
|
//
|
31
SieveUnitTests/Services/ApplicationSieveProcessor.cs
Normal file
31
SieveUnitTests/Services/ApplicationSieveProcessor.cs
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
using Microsoft.Extensions.Options;
|
||||||
|
using Sieve.Models;
|
||||||
|
using Sieve.Services;
|
||||||
|
using SieveUnitTests.Entities;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
|
namespace SieveUnitTests.Services
|
||||||
|
{
|
||||||
|
public class ApplicationSieveProcessor : SieveProcessor
|
||||||
|
{
|
||||||
|
public ApplicationSieveProcessor(IOptions<SieveOptions> options, ISieveCustomSortMethods customSortMethods, ISieveCustomFilterMethods customFilterMethods) : base(options, customSortMethods, customFilterMethods)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override SievePropertyMapper MapProperties(SievePropertyMapper mapper)
|
||||||
|
{
|
||||||
|
mapper.Property<Post>(p => p.ThisHasNoAttributeButIsAccessible)
|
||||||
|
.CanSort()
|
||||||
|
.CanFilter()
|
||||||
|
.HasName("shortname");
|
||||||
|
|
||||||
|
mapper.Property<Post>(p => p.OnlySortableViaFluentApi)
|
||||||
|
.CanSort();
|
||||||
|
|
||||||
|
return mapper;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user