mirror of
				https://github.com/Biarity/Sieve.git
				synced 2025-11-04 10:49:09 +01:00 
			
		
		
		
	Base & test solution
This commit is contained in:
		@@ -5,6 +5,8 @@ VisualStudioVersion = 15.0.27130.2010
 | 
				
			|||||||
MinimumVisualStudioVersion = 10.0.40219.1
 | 
					MinimumVisualStudioVersion = 10.0.40219.1
 | 
				
			||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sieve", "Sieve\Sieve.csproj", "{B32B8B33-94B0-40E3-8FE5-D54602222717}"
 | 
					Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sieve", "Sieve\Sieve.csproj", "{B32B8B33-94B0-40E3-8FE5-D54602222717}"
 | 
				
			||||||
EndProject
 | 
					EndProject
 | 
				
			||||||
 | 
					Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SieveTests", "SieveTests\SieveTests.csproj", "{8043D264-42A0-4275-97A1-46400C02E37E}"
 | 
				
			||||||
 | 
					EndProject
 | 
				
			||||||
Global
 | 
					Global
 | 
				
			||||||
	GlobalSection(SolutionConfigurationPlatforms) = preSolution
 | 
						GlobalSection(SolutionConfigurationPlatforms) = preSolution
 | 
				
			||||||
		Debug|Any CPU = Debug|Any CPU
 | 
							Debug|Any CPU = Debug|Any CPU
 | 
				
			||||||
@@ -15,6 +17,10 @@ Global
 | 
				
			|||||||
		{B32B8B33-94B0-40E3-8FE5-D54602222717}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
							{B32B8B33-94B0-40E3-8FE5-D54602222717}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
				
			||||||
		{B32B8B33-94B0-40E3-8FE5-D54602222717}.Release|Any CPU.ActiveCfg = Release|Any CPU
 | 
							{B32B8B33-94B0-40E3-8FE5-D54602222717}.Release|Any CPU.ActiveCfg = Release|Any CPU
 | 
				
			||||||
		{B32B8B33-94B0-40E3-8FE5-D54602222717}.Release|Any CPU.Build.0 = Release|Any CPU
 | 
							{B32B8B33-94B0-40E3-8FE5-D54602222717}.Release|Any CPU.Build.0 = Release|Any CPU
 | 
				
			||||||
 | 
							{8043D264-42A0-4275-97A1-46400C02E37E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
 | 
				
			||||||
 | 
							{8043D264-42A0-4275-97A1-46400C02E37E}.Debug|Any CPU.Build.0 = Debug|Any CPU
 | 
				
			||||||
 | 
							{8043D264-42A0-4275-97A1-46400C02E37E}.Release|Any CPU.ActiveCfg = Release|Any CPU
 | 
				
			||||||
 | 
							{8043D264-42A0-4275-97A1-46400C02E37E}.Release|Any CPU.Build.0 = Release|Any CPU
 | 
				
			||||||
	EndGlobalSection
 | 
						EndGlobalSection
 | 
				
			||||||
	GlobalSection(SolutionProperties) = preSolution
 | 
						GlobalSection(SolutionProperties) = preSolution
 | 
				
			||||||
		HideSolutionNode = FALSE
 | 
							HideSolutionNode = FALSE
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										18
									
								
								Sieve/Attributes/SieveAttribute.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										18
									
								
								Sieve/Attributes/SieveAttribute.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,18 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Sieve.Attributes
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
 | 
				
			||||||
 | 
					    class SieveAttribute : Attribute
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        /// <summary>
 | 
				
			||||||
 | 
					        /// Override name used 
 | 
				
			||||||
 | 
					        /// </summary>
 | 
				
			||||||
 | 
					        public string Name { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public bool CanSort { get; set; }
 | 
				
			||||||
 | 
					        public bool CanFilter { get; set; }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -1,8 +0,0 @@
 | 
				
			|||||||
using System;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
namespace Sieve
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    public class Class1
 | 
					 | 
				
			||||||
    {
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
							
								
								
									
										31
									
								
								Sieve/Extensions/OrderByWithDirection.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										31
									
								
								Sieve/Extensions/OrderByWithDirection.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,31 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Linq.Expressions;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Sieve.Extensions
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public static class LinqExtensions
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public static IOrderedEnumerable<TSource> OrderByWithDirection<TSource, TKey>
 | 
				
			||||||
 | 
					            (this IEnumerable<TSource> source,
 | 
				
			||||||
 | 
					             Func<TSource, TKey> keySelector,
 | 
				
			||||||
 | 
					             bool descending)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return descending ? source.OrderByDescending(keySelector)
 | 
				
			||||||
 | 
					                              : source.OrderBy(keySelector);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static IOrderedQueryable<TSource> OrderByWithDirection<TSource, TKey>
 | 
				
			||||||
 | 
					            (this IQueryable<TSource> source,
 | 
				
			||||||
 | 
					             Expression<Func<TSource, TKey>> keySelector,
 | 
				
			||||||
 | 
					             bool descending)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return descending ? source.OrderByDescending(keySelector)
 | 
				
			||||||
 | 
					                              : source.OrderBy(keySelector);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										17
									
								
								Sieve/Models/FilterOperator.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								Sieve/Models/FilterOperator.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Sieve.Models
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public enum FilterOperator
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        Equals,
 | 
				
			||||||
 | 
					        GreaterThan,
 | 
				
			||||||
 | 
					        LessThan,
 | 
				
			||||||
 | 
					        GreaterThanOrEqualTo,
 | 
				
			||||||
 | 
					        LessThanOrEqualTo,
 | 
				
			||||||
 | 
					        Contains,
 | 
				
			||||||
 | 
					        StartsWith
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										58
									
								
								Sieve/Models/FilterTerm.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										58
									
								
								Sieve/Models/FilterTerm.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,58 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using Microsoft.AspNetCore.Mvc.ModelBinding;
 | 
				
			||||||
 | 
					using System.ComponentModel.DataAnnotations;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Sieve.Models
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class FilterTerm
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public string Name { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string Operator { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [BindNever]
 | 
				
			||||||
 | 
					        public FilterOperator OperatorParsed {
 | 
				
			||||||
 | 
					            get {
 | 
				
			||||||
 | 
					                switch (Operator.Trim().ToLower())
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    case "equals":
 | 
				
			||||||
 | 
					                    case "eq":
 | 
				
			||||||
 | 
					                    case "==":
 | 
				
			||||||
 | 
					                        return FilterOperator.Equals;
 | 
				
			||||||
 | 
					                    case "lessthan":
 | 
				
			||||||
 | 
					                    case "lt":
 | 
				
			||||||
 | 
					                    case "<":
 | 
				
			||||||
 | 
					                        return FilterOperator.LessThan;
 | 
				
			||||||
 | 
					                    case "greaterthan":
 | 
				
			||||||
 | 
					                    case "gt":
 | 
				
			||||||
 | 
					                    case ">":
 | 
				
			||||||
 | 
					                        return FilterOperator.GreaterThan;
 | 
				
			||||||
 | 
					                    case "greaterthanorequalto":
 | 
				
			||||||
 | 
					                    case "gte":
 | 
				
			||||||
 | 
					                    case ">=":
 | 
				
			||||||
 | 
					                        return FilterOperator.GreaterThanOrEqualTo;
 | 
				
			||||||
 | 
					                    case "lessthanorequalto":
 | 
				
			||||||
 | 
					                    case "lte":
 | 
				
			||||||
 | 
					                    case "<=":
 | 
				
			||||||
 | 
					                        return FilterOperator.LessThanOrEqualTo;
 | 
				
			||||||
 | 
					                    case "contains":
 | 
				
			||||||
 | 
					                    case "co":
 | 
				
			||||||
 | 
					                    case "@=":
 | 
				
			||||||
 | 
					                        return FilterOperator.Contains;
 | 
				
			||||||
 | 
					                    case "startswith":
 | 
				
			||||||
 | 
					                    case "sw":
 | 
				
			||||||
 | 
					                    case "_=":
 | 
				
			||||||
 | 
					                        return FilterOperator.StartsWith;
 | 
				
			||||||
 | 
					                    default:
 | 
				
			||||||
 | 
					                        return FilterOperator.Equals;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public string Value { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public bool Descending { get; set; } = false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										20
									
								
								Sieve/Models/SieveModel.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										20
									
								
								Sieve/Models/SieveModel.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,20 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.ComponentModel.DataAnnotations;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Sieve.Models
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class SieveModel
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public IEnumerable<FilterTerm> Filter { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IEnumerable<SortTerm> Sort { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Range(1, Double.MaxValue)]
 | 
				
			||||||
 | 
					        public int Page { get; set; } = 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        [Range(1, Double.MaxValue)]
 | 
				
			||||||
 | 
					        public int PageSize { get; set; } = 10;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										10
									
								
								Sieve/Models/SieveOptions.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								Sieve/Models/SieveOptions.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Sieve.Models
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class SieveOptions
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										14
									
								
								Sieve/Models/SortTerm.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								Sieve/Models/SortTerm.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,14 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.ComponentModel.DataAnnotations;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Sieve.Models
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class SortTerm
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public string Name { get; set; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public bool Descending { get; set; } = false;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										15
									
								
								Sieve/Services/ISieveCustomFilterMethods.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								Sieve/Services/ISieveCustomFilterMethods.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Sieve.Services
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public interface ISieveCustomFilterMethods
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public interface ISieveCustomFilterMethods<TEntity>
 | 
				
			||||||
 | 
					    where TEntity : class
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										15
									
								
								Sieve/Services/ISieveCustomSortMethods.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								Sieve/Services/ISieveCustomSortMethods.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Sieve.Services
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public interface ISieveCustomSortMethods
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public interface ISieveCustomSortMethods<TEntity>
 | 
				
			||||||
 | 
					        where TEntity : class
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										151
									
								
								Sieve/Services/SieveProcessor.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										151
									
								
								Sieve/Services/SieveProcessor.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,151 @@
 | 
				
			|||||||
 | 
					using Microsoft.Extensions.Options;
 | 
				
			||||||
 | 
					using Sieve.Models;
 | 
				
			||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Text;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					using System.Data.Entity;
 | 
				
			||||||
 | 
					using System.Reflection;
 | 
				
			||||||
 | 
					using Sieve.Attributes;
 | 
				
			||||||
 | 
					using Sieve.Extensions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace Sieve.Services
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class SieveProcessor<TEntity>
 | 
				
			||||||
 | 
					        where TEntity: class
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        private IOptions<SieveOptions> _options;
 | 
				
			||||||
 | 
					        private ISieveCustomSortMethods<TEntity> _customSortMethods;
 | 
				
			||||||
 | 
					        private ISieveCustomFilterMethods<TEntity> _customFilterMethods;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public SieveProcessor(IOptions<SieveOptions> options,
 | 
				
			||||||
 | 
					            ISieveCustomSortMethods<TEntity> customSortMethods,
 | 
				
			||||||
 | 
					            ISieveCustomFilterMethods<TEntity> customFilterMethods)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            _options = options;
 | 
				
			||||||
 | 
					            _customSortMethods = customSortMethods;
 | 
				
			||||||
 | 
					            _customFilterMethods = customFilterMethods;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IEnumerable<TEntity> ApplyAll(SieveModel model, IQueryable<TEntity> source)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            var result = source.AsNoTracking();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Sort
 | 
				
			||||||
 | 
					            result = ApplySort(model, result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Filter
 | 
				
			||||||
 | 
					            result = ApplyFilter(model, result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            // Paginate
 | 
				
			||||||
 | 
					            result = ApplyPagination(model, result);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return result;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IQueryable<TEntity> ApplySort(SieveModel model, IQueryable<TEntity> result)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            foreach (var sortTerm in model.Sort)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var property = GetSieveProperty(true, false, sortTerm.Name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (property != null)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    result = result.OrderByWithDirection(
 | 
				
			||||||
 | 
					                        e => property.GetValue(e),
 | 
				
			||||||
 | 
					                        sortTerm.Descending);
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    var customMethod = _customSortMethods.GetType()
 | 
				
			||||||
 | 
					                        .GetMethod(sortTerm.Name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (customMethod != null)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        result = result.OrderByWithDirection(
 | 
				
			||||||
 | 
					                            e => customMethod.Invoke(_customSortMethods, new object[] { e }),
 | 
				
			||||||
 | 
					                            sortTerm.Descending);
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return result;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IQueryable<TEntity> ApplyFilter(SieveModel model, IQueryable<TEntity> result)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            foreach (var filterTerm in model.Filter)
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                var property = GetSieveProperty(false, true, filterTerm.Name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                if (property != null)
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    var filterValue = Convert.ChangeType(filterTerm.Value, property.GetType());
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                    switch (filterTerm.OperatorParsed)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        case FilterOperator.Equals:
 | 
				
			||||||
 | 
					                            result = result.Where(e => ((IComparable)property.GetValue(e)).Equals(filterValue));
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        case FilterOperator.GreaterThan:
 | 
				
			||||||
 | 
					                            result = result.Where(e => ((IComparable)property.GetValue(e)).CompareTo(filterValue) > 0);
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        case FilterOperator.LessThan:
 | 
				
			||||||
 | 
					                            result = result.Where(e => ((IComparable)property.GetValue(e)).CompareTo(filterValue) < 0);
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        case FilterOperator.GreaterThanOrEqualTo:
 | 
				
			||||||
 | 
					                            result = result.Where(e => ((IComparable)property.GetValue(e)).CompareTo(filterValue) >= 0);
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        case FilterOperator.LessThanOrEqualTo:
 | 
				
			||||||
 | 
					                            result = result.Where(e => ((IComparable)property.GetValue(e)).CompareTo(filterValue) <= 0);
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        case FilterOperator.Contains:
 | 
				
			||||||
 | 
					                            result = result.Where(e => ((string)property.GetValue(e)).Contains((string)filterValue));
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        case FilterOperator.StartsWith:
 | 
				
			||||||
 | 
					                            result = result.Where(e => ((string)property.GetValue(e)).StartsWith((string)filterValue));
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                        default:
 | 
				
			||||||
 | 
					                            result = result.Where(e => ((IComparable)property.GetValue(e)).Equals(filterValue));
 | 
				
			||||||
 | 
					                            break;
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					                else
 | 
				
			||||||
 | 
					                {
 | 
				
			||||||
 | 
					                    var customMethod = _customFilterMethods.GetType()
 | 
				
			||||||
 | 
					                        .GetMethod(filterTerm.Name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                    if (customMethod != null)
 | 
				
			||||||
 | 
					                    {
 | 
				
			||||||
 | 
					                        result = result.Where(
 | 
				
			||||||
 | 
					                            e => (bool)customMethod.Invoke(_customFilterMethods, new object[] { e }));
 | 
				
			||||||
 | 
					                    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            return result;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IQueryable<TEntity> ApplyPagination(SieveModel model, IQueryable<TEntity> result)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            result = result.Skip((model.Page - 1) * model.PageSize)
 | 
				
			||||||
 | 
					                .Take(model.PageSize);
 | 
				
			||||||
 | 
					            return result;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private  PropertyInfo GetSieveProperty(bool canSortRequired, bool canFilterRequired, string name)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return typeof(TEntity).GetProperties().FirstOrDefault(p =>
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                if (p.GetCustomAttribute(typeof(SieveAttribute)) is SieveAttribute sieveAttribute)
 | 
				
			||||||
 | 
					                    if ((canSortRequired ? sieveAttribute.CanSort : true) &&
 | 
				
			||||||
 | 
					                        (canFilterRequired ? sieveAttribute.CanFilter : true) &&
 | 
				
			||||||
 | 
					                        ((sieveAttribute.Name ?? p.Name) == name))
 | 
				
			||||||
 | 
					                        return true;
 | 
				
			||||||
 | 
					                return false;
 | 
				
			||||||
 | 
					            });
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -4,4 +4,10 @@
 | 
				
			|||||||
    <TargetFramework>netcoreapp2.0</TargetFramework>
 | 
					    <TargetFramework>netcoreapp2.0</TargetFramework>
 | 
				
			||||||
  </PropertyGroup>
 | 
					  </PropertyGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
					    <PackageReference Include="EntityFramework" Version="6.2.0" />
 | 
				
			||||||
 | 
					    <PackageReference Include="Microsoft.AspNetCore.Mvc.Core" Version="2.0.2" />
 | 
				
			||||||
 | 
					    <PackageReference Include="Microsoft.Extensions.Options" Version="2.0.0" />
 | 
				
			||||||
 | 
					  </ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
</Project>
 | 
					</Project>
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										44
									
								
								SieveTests/Controllers/ValuesController.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								SieveTests/Controllers/ValuesController.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,44 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					using Microsoft.AspNetCore.Mvc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace SieveTests.Controllers
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    [Route("api/[controller]")]
 | 
				
			||||||
 | 
					    public class ValuesController : Controller
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        // GET api/values
 | 
				
			||||||
 | 
					        [HttpGet]
 | 
				
			||||||
 | 
					        public IEnumerable<string> Get()
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return new string[] { "value1", "value2" };
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // GET api/values/5
 | 
				
			||||||
 | 
					        [HttpGet("{id}")]
 | 
				
			||||||
 | 
					        public string Get(int id)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            return "value";
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // POST api/values
 | 
				
			||||||
 | 
					        [HttpPost]
 | 
				
			||||||
 | 
					        public void Post([FromBody]string value)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // PUT api/values/5
 | 
				
			||||||
 | 
					        [HttpPut("{id}")]
 | 
				
			||||||
 | 
					        public void Put(int id, [FromBody]string value)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // DELETE api/values/5
 | 
				
			||||||
 | 
					        [HttpDelete("{id}")]
 | 
				
			||||||
 | 
					        public void Delete(int id)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										25
									
								
								SieveTests/Program.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										25
									
								
								SieveTests/Program.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,25 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.IO;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					using Microsoft.AspNetCore;
 | 
				
			||||||
 | 
					using Microsoft.AspNetCore.Hosting;
 | 
				
			||||||
 | 
					using Microsoft.Extensions.Configuration;
 | 
				
			||||||
 | 
					using Microsoft.Extensions.Logging;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace SieveTests
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class Program
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public static void Main(string[] args)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            BuildWebHost(args).Run();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public static IWebHost BuildWebHost(string[] args) =>
 | 
				
			||||||
 | 
					            WebHost.CreateDefaultBuilder(args)
 | 
				
			||||||
 | 
					                .UseStartup<Startup>()
 | 
				
			||||||
 | 
					                .Build();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										29
									
								
								SieveTests/Properties/launchSettings.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										29
									
								
								SieveTests/Properties/launchSettings.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,29 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "iisSettings": {
 | 
				
			||||||
 | 
					    "windowsAuthentication": false,
 | 
				
			||||||
 | 
					    "anonymousAuthentication": true,
 | 
				
			||||||
 | 
					    "iisExpress": {
 | 
				
			||||||
 | 
					      "applicationUrl": "http://localhost:65136/",
 | 
				
			||||||
 | 
					      "sslPort": 0
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
 | 
					  "profiles": {
 | 
				
			||||||
 | 
					    "IIS Express": {
 | 
				
			||||||
 | 
					      "commandName": "IISExpress",
 | 
				
			||||||
 | 
					      "launchBrowser": true,
 | 
				
			||||||
 | 
					      "launchUrl": "api/values",
 | 
				
			||||||
 | 
					      "environmentVariables": {
 | 
				
			||||||
 | 
					        "ASPNETCORE_ENVIRONMENT": "Development"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "SieveTests": {
 | 
				
			||||||
 | 
					      "commandName": "Project",
 | 
				
			||||||
 | 
					      "launchBrowser": true,
 | 
				
			||||||
 | 
					      "launchUrl": "api/values",
 | 
				
			||||||
 | 
					      "environmentVariables": {
 | 
				
			||||||
 | 
					        "ASPNETCORE_ENVIRONMENT": "Development"
 | 
				
			||||||
 | 
					      },
 | 
				
			||||||
 | 
					      "applicationUrl": "http://localhost:65137/"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										19
									
								
								SieveTests/SieveTests.csproj
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										19
									
								
								SieveTests/SieveTests.csproj
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,19 @@
 | 
				
			|||||||
 | 
					<Project Sdk="Microsoft.NET.Sdk.Web">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <PropertyGroup>
 | 
				
			||||||
 | 
					    <TargetFramework>netcoreapp2.0</TargetFramework>
 | 
				
			||||||
 | 
					  </PropertyGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
					    <Folder Include="wwwroot\" />
 | 
				
			||||||
 | 
					  </ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
					    <PackageReference Include="Microsoft.AspNetCore.All" Version="2.0.3" />
 | 
				
			||||||
 | 
					  </ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <ItemGroup>
 | 
				
			||||||
 | 
					    <DotNetCliToolReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Tools" Version="2.0.1" />
 | 
				
			||||||
 | 
					  </ItemGroup>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					</Project>
 | 
				
			||||||
							
								
								
									
										40
									
								
								SieveTests/Startup.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								SieveTests/Startup.cs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
				
			|||||||
 | 
					using System;
 | 
				
			||||||
 | 
					using System.Collections.Generic;
 | 
				
			||||||
 | 
					using System.Linq;
 | 
				
			||||||
 | 
					using System.Threading.Tasks;
 | 
				
			||||||
 | 
					using Microsoft.AspNetCore.Builder;
 | 
				
			||||||
 | 
					using Microsoft.AspNetCore.Hosting;
 | 
				
			||||||
 | 
					using Microsoft.Extensions.Configuration;
 | 
				
			||||||
 | 
					using Microsoft.Extensions.DependencyInjection;
 | 
				
			||||||
 | 
					using Microsoft.Extensions.Logging;
 | 
				
			||||||
 | 
					using Microsoft.Extensions.Options;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					namespace SieveTests
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    public class Startup
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					        public Startup(IConfiguration configuration)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            Configuration = configuration;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        public IConfiguration Configuration { get; }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // This method gets called by the runtime. Use this method to add services to the container.
 | 
				
			||||||
 | 
					        public void ConfigureServices(IServiceCollection services)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            services.AddMvc();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
 | 
				
			||||||
 | 
					        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            if (env.IsDevelopment())
 | 
				
			||||||
 | 
					            {
 | 
				
			||||||
 | 
					                app.UseDeveloperExceptionPage();
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            app.UseMvc();
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										10
									
								
								SieveTests/appsettings.Development.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										10
									
								
								SieveTests/appsettings.Development.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "Logging": {
 | 
				
			||||||
 | 
					    "IncludeScopes": false,
 | 
				
			||||||
 | 
					    "LogLevel": {
 | 
				
			||||||
 | 
					      "Default": "Debug",
 | 
				
			||||||
 | 
					      "System": "Information",
 | 
				
			||||||
 | 
					      "Microsoft": "Information"
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										15
									
								
								SieveTests/appsettings.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										15
									
								
								SieveTests/appsettings.json
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,15 @@
 | 
				
			|||||||
 | 
					{
 | 
				
			||||||
 | 
					  "Logging": {
 | 
				
			||||||
 | 
					    "IncludeScopes": false,
 | 
				
			||||||
 | 
					    "Debug": {
 | 
				
			||||||
 | 
					      "LogLevel": {
 | 
				
			||||||
 | 
					        "Default": "Warning"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
 | 
					    "Console": {
 | 
				
			||||||
 | 
					      "LogLevel": {
 | 
				
			||||||
 | 
					        "Default": "Warning"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Reference in New Issue
	
	Block a user