Эх сурвалжийг харах

rename QueryBuilder to Filter
#gogs14_2024-01-19_SupportMethodLikeCount

lith 1 жил өмнө
parent
commit
993e9846ce
35 өөрчлөгдсөн 443 нэмэгдсэн , 75 устгасан
  1. 8 0
      readme.md
  2. 2 2
      src/Test/Vit.Linq.MsTest/Filter/CustomeValue_Test.cs
  3. 1 1
      src/Test/Vit.Linq.MsTest/Filter/Filter_TestBase.cs
  4. 3 3
      src/Test/Vit.Linq.MsTest/Filter/IQueryableTest/Filter_Test_FilterRule.cs
  5. 3 3
      src/Test/Vit.Linq.MsTest/Filter/IQueryableTest/Filter_Test_FilterRuleWithMethod.cs
  6. 4 4
      src/Test/Vit.Linq.MsTest/Filter/IQueryableTest/Filter_Test_Newtonsoft.cs
  7. 4 4
      src/Test/Vit.Linq.MsTest/Filter/IQueryableTest/Filter_Test_Newtonsoft2.cs
  8. 4 4
      src/Test/Vit.Linq.MsTest/Filter/IQueryableTest/Filter_Test_SystemTextJson.cs
  9. 4 4
      src/Test/Vit.Linq.MsTest/Filter/IQueryableTest/Filter_Test_SystemTextJson2.cs
  10. 2 2
      src/Test/Vit.Linq.MsTest/Filter/OperatorMap_Test.cs
  11. 3 3
      src/Test/Vit.Linq.MsTest/Filter/QueryableTest/Filter_Test_FilterRule.cs
  12. 3 3
      src/Test/Vit.Linq.MsTest/Filter/QueryableTest/Filter_Test_FilterRuleWithMethod.cs
  13. 4 4
      src/Test/Vit.Linq.MsTest/Filter/QueryableTest/Filter_Test_Newtonsoft.cs
  14. 4 4
      src/Test/Vit.Linq.MsTest/Filter/QueryableTest/Filter_Test_Newtonsoft2.cs
  15. 4 4
      src/Test/Vit.Linq.MsTest/Filter/QueryableTest/Filter_Test_SystemTextJson.cs
  16. 4 4
      src/Test/Vit.Linq.MsTest/Filter/QueryableTest/Filter_Test_SystemTextJson2.cs
  17. 1 1
      src/Test/Vit.Linq.MsTest31/Vit.Linq.MsTest31.csproj
  18. 1 1
      src/Vit.Linq.Extensions/Extensions/IQueryable_Sort_Extensions.cs
  19. 2 3
      src/Vit.Linq.Extensions/Extensions/Queryable_Sort_ByReflection_Extensions.cs
  20. 2 1
      src/Vit.Linq.Extensions/Extensions/Queryable_Sort_Extensions.cs
  21. 1 1
      src/Vit.Linq.NewtonsoftJson/FilterRule_Newtonsoft.cs
  22. 1 1
      src/Vit.Linq.SystemTextJson/FilterRule_SystemTextJson.cs
  23. 1 1
      src/Vit.Linq/Filter/ECondition.cs
  24. 3 3
      src/Vit.Linq/Filter/Extensions/IQueryable_Where_Extensions.cs
  25. 3 3
      src/Vit.Linq/Filter/Extensions/Queryable_Where_Extensions.cs
  26. 1 1
      src/Vit.Linq/Filter/FilterRule.cs
  27. 1 1
      src/Vit.Linq/Filter/FilterRuleBase.cs
  28. 1 1
      src/Vit.Linq/Filter/FilterRuleOperator.cs
  29. 364 0
      src/Vit.Linq/Filter/FilterService.cs
  30. 1 1
      src/Vit.Linq/Filter/IFilterRule.cs
  31. 0 0
      src/Vit.Linq/Filter/QueryBuilderService.cs
  32. 1 1
      src/Vit.Linq/LinqHelp.Reflection.cs
  33. 1 2
      src/Vit.Linq/LinqHelp.cs
  34. 1 1
      src/Vit.Linq/MoreFilter/FilterRuleWithMethod.cs
  35. 0 3
      src/Vit.Linq/readme.md

+ 8 - 0
readme.md

@@ -0,0 +1,8 @@
+
+# Linq Filter Library
+Compatible with QueryBuilder
+
+example :   [Test](src/Test/Vit.Linq.MsTest/Filter/Filter_TestBase.cs)
+
+
+ref DynamicQueryable

+ 2 - 2
src/Test/Vit.Linq.MsTest/QueryBuilder/CustomeValue_Test.cs → src/Test/Vit.Linq.MsTest/Filter/CustomeValue_Test.cs

@@ -5,7 +5,7 @@ using System.Text;
 
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Vit.Core.Module.Serialization;
-using Vit.Linq.QueryBuilder;
+using Vit.Linq.Filter;
 using Vit.Extensions.Linq_Extensions;
 using Newtonsoft.Json.Linq;
 
@@ -19,7 +19,7 @@ namespace Vit.Linq.MsTest.QueryBuilder
         public void Test_CustomeValue()
         {
             {
-                var service = new QueryBuilderService();
+                var service = new FilterService();
                 service.GetRuleValue = (object? value, IFilterRule rule, Type fieldType) =>
                 {
                     // to deal with null value

+ 1 - 1
src/Test/Vit.Linq.MsTest/QueryBuilder/Filter_TestBase.cs → src/Test/Vit.Linq.MsTest/Filter/Filter_TestBase.cs

@@ -6,7 +6,7 @@ using System.Linq;
 using System.Reflection;
 
 using Vit.Linq.MoreFilter;
-using Vit.Linq.QueryBuilder;
+using Vit.Linq.Filter;
 
 namespace Vit.Linq.MsTest.QueryBuilder
 {

+ 3 - 3
src/Test/Vit.Linq.MsTest/QueryBuilder/IQueryableTest/Filter_Test_FilterRule.cs → src/Test/Vit.Linq.MsTest/Filter/IQueryableTest/Filter_Test_FilterRule.cs

@@ -3,7 +3,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
 using System.Collections.Generic;
 using System.Linq;
 using Vit.Core.Module.Serialization;
-using Vit.Linq.QueryBuilder;
+using Vit.Linq.Filter;
 using System;
 using Newtonsoft.Json.Linq;
 using Queryable = System.Linq.IQueryable;
@@ -33,9 +33,9 @@ namespace Vit.Linq.MsTest.QueryBuilder.IQueryableTest
             return query.IQueryable_Where(rule, GetService()).IQueryable_ToList<ModelA>();
         }
 
-        public virtual QueryBuilderService GetService()
+        public virtual FilterService GetService()
         {
-            QueryBuilderService service = new QueryBuilderService();
+            FilterService service = new FilterService();
             service.GetRuleValue = (object value, IFilterRule rule, Type fieldType) =>
             {
                 // to deal with null value

+ 3 - 3
src/Test/Vit.Linq.MsTest/QueryBuilder/IQueryableTest/Filter_Test_FilterRuleWithMethod.cs → src/Test/Vit.Linq.MsTest/Filter/IQueryableTest/Filter_Test_FilterRuleWithMethod.cs

@@ -1,6 +1,6 @@
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Vit.Core.Module.Serialization;
-using Vit.Linq.QueryBuilder;
+using Vit.Linq.Filter;
 using Vit.Linq.MoreFilter;
 using Newtonsoft.Json.Linq;
 using System;
@@ -21,9 +21,9 @@ namespace Vit.Linq.MsTest.QueryBuilder.IQueryableTest
             return Json.Deserialize<FilterRuleWithMethod>(filterRule);
         }
 
-        public virtual QueryBuilderService GetService()
+        public virtual FilterService GetService()
         {
-            QueryBuilderService service = new QueryBuilderService();
+            FilterService service = new FilterService();
             service.GetRuleValue = (object value, IFilterRule rule, Type fieldType) =>
             {
                 // to deal with null value

+ 4 - 4
src/Test/Vit.Linq.MsTest/QueryBuilder/IQueryableTest/Filter_Test_Newtonsoft.cs → src/Test/Vit.Linq.MsTest/Filter/IQueryableTest/Filter_Test_Newtonsoft.cs

@@ -1,8 +1,8 @@
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 
 using Vit.Core.Module.Serialization;
-using Vit.Linq.QueryBuilder;
-using Vit.Linq.QueryBuilder.NewtonsoftJson;
+using Vit.Linq.Filter;
+using Vit.Linq.NewtonsoftJson;
 
 namespace Vit.Linq.MsTest.QueryBuilder.IQueryableTest
 {
@@ -21,9 +21,9 @@ namespace Vit.Linq.MsTest.QueryBuilder.IQueryableTest
             return Json.Deserialize<FilterRule_Newtonsoft>(filterRule);
         }
 
-        public override QueryBuilderService GetService()
+        public override FilterService GetService()
         {
-            QueryBuilderService service = new QueryBuilderService();
+            FilterService service = new FilterService();
             return service;
         }
 

+ 4 - 4
src/Test/Vit.Linq.MsTest/QueryBuilder/IQueryableTest/Filter_Test_Newtonsoft2.cs → src/Test/Vit.Linq.MsTest/Filter/IQueryableTest/Filter_Test_Newtonsoft2.cs

@@ -1,7 +1,7 @@
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 
-using Vit.Linq.QueryBuilder;
-using Vit.Linq.QueryBuilder.NewtonsoftJson;
+using Vit.Linq.Filter;
+using Vit.Linq.NewtonsoftJson;
 
 namespace Vit.Linq.MsTest.QueryBuilder.IQueryableTest
 {
@@ -18,9 +18,9 @@ namespace Vit.Linq.MsTest.QueryBuilder.IQueryableTest
         {
             return FilterRule_Newtonsoft.FromString(filterRule);
         }
-        public override QueryBuilderService GetService()
+        public override FilterService GetService()
         {
-            QueryBuilderService service = new QueryBuilderService();
+            FilterService service = new FilterService();
             return service;
         }
 

+ 4 - 4
src/Test/Vit.Linq.MsTest/QueryBuilder/IQueryableTest/Filter_Test_SystemTextJson.cs → src/Test/Vit.Linq.MsTest/Filter/IQueryableTest/Filter_Test_SystemTextJson.cs

@@ -2,8 +2,8 @@
 
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 
-using Vit.Linq.QueryBuilder;
-using Vit.Linq.QueryBuilder.SystemTextJson;
+using Vit.Linq.Filter;
+using Vit.Linq.SystemTextJson;
 
 namespace Vit.Linq.MsTest.QueryBuilder.IQueryableTest
 {
@@ -21,9 +21,9 @@ namespace Vit.Linq.MsTest.QueryBuilder.IQueryableTest
             return JsonSerializer.Deserialize<FilterRule_SystemTextJson>(filterRule);
         }
 
-        public override QueryBuilderService GetService()
+        public override FilterService GetService()
         {
-            QueryBuilderService service = new QueryBuilderService();
+            FilterService service = new FilterService();
             return service;
         }
 

+ 4 - 4
src/Test/Vit.Linq.MsTest/QueryBuilder/IQueryableTest/Filter_Test_SystemTextJson2.cs → src/Test/Vit.Linq.MsTest/Filter/IQueryableTest/Filter_Test_SystemTextJson2.cs

@@ -1,7 +1,7 @@
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 
-using Vit.Linq.QueryBuilder;
-using Vit.Linq.QueryBuilder.SystemTextJson;
+using Vit.Linq.Filter;
+using Vit.Linq.SystemTextJson;
 
 namespace Vit.Linq.MsTest.QueryBuilder.IQueryableTest
 {
@@ -20,9 +20,9 @@ namespace Vit.Linq.MsTest.QueryBuilder.IQueryableTest
             return FilterRule_SystemTextJson.FromString(filterRule);
         }
 
-        public override QueryBuilderService GetService()
+        public override FilterService GetService()
         {
-            QueryBuilderService service = new QueryBuilderService();
+            FilterService service = new FilterService();
             return service;
         }
     }

+ 2 - 2
src/Test/Vit.Linq.MsTest/QueryBuilder/OperatorMap_Test.cs → src/Test/Vit.Linq.MsTest/Filter/OperatorMap_Test.cs

@@ -2,7 +2,7 @@
 
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Vit.Core.Module.Serialization;
-using Vit.Linq.QueryBuilder;
+using Vit.Linq.Filter;
 using Vit.Extensions.Linq_Extensions;
 
 namespace Vit.Linq.MsTest.QueryBuilder
@@ -15,7 +15,7 @@ namespace Vit.Linq.MsTest.QueryBuilder
         public void Test_OperatorMap()
         {
             {
-                var service = new QueryBuilderService();
+                var service = new FilterService();
                 var query = DataSource.GetQueryable();
                 service.AddOperatorMap("Equal", FilterRuleOperator.Equal);
 

+ 3 - 3
src/Test/Vit.Linq.MsTest/QueryBuilder/QueryableTest/Filter_Test_FilterRule.cs → src/Test/Vit.Linq.MsTest/Filter/QueryableTest/Filter_Test_FilterRule.cs

@@ -3,7 +3,7 @@ using Microsoft.VisualStudio.TestTools.UnitTesting;
 using System.Collections.Generic;
 using System.Linq;
 using Vit.Core.Module.Serialization;
-using Vit.Linq.QueryBuilder;
+using Vit.Linq.Filter;
 using System;
 using Newtonsoft.Json.Linq;
 using Queryable = System.Linq.IQueryable<Vit.Linq.MsTest.ModelA>;
@@ -33,9 +33,9 @@ namespace Vit.Linq.MsTest.QueryBuilder.QueryableTest
             return query.Where(rule, GetService()).ToList<ModelA>();
         }
 
-        public virtual QueryBuilderService GetService()
+        public virtual FilterService GetService()
         {
-            QueryBuilderService service = new QueryBuilderService();
+            FilterService service = new FilterService();
             service.GetRuleValue = (object value, IFilterRule rule, Type fieldType) =>
             {
                 // to deal with null value

+ 3 - 3
src/Test/Vit.Linq.MsTest/QueryBuilder/QueryableTest/Filter_Test_FilterRuleWithMethod.cs → src/Test/Vit.Linq.MsTest/Filter/QueryableTest/Filter_Test_FilterRuleWithMethod.cs

@@ -1,6 +1,6 @@
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using Vit.Core.Module.Serialization;
-using Vit.Linq.QueryBuilder;
+using Vit.Linq.Filter;
 using Vit.Linq.MoreFilter;
 using Newtonsoft.Json.Linq;
 using System;
@@ -21,9 +21,9 @@ namespace Vit.Linq.MsTest.QueryBuilder.QueryableTest
             return Json.Deserialize<FilterRuleWithMethod>(filterRule);
         }
 
-        public virtual QueryBuilderService GetService()
+        public virtual FilterService GetService()
         {
-            QueryBuilderService service = new QueryBuilderService();
+            FilterService service = new FilterService();
             service.GetRuleValue = (object value, IFilterRule rule, Type fieldType) =>
             {
                 // to deal with null value

+ 4 - 4
src/Test/Vit.Linq.MsTest/QueryBuilder/QueryableTest/Filter_Test_Newtonsoft.cs → src/Test/Vit.Linq.MsTest/Filter/QueryableTest/Filter_Test_Newtonsoft.cs

@@ -1,8 +1,8 @@
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 
 using Vit.Core.Module.Serialization;
-using Vit.Linq.QueryBuilder;
-using Vit.Linq.QueryBuilder.NewtonsoftJson;
+using Vit.Linq.Filter;
+using Vit.Linq.NewtonsoftJson;
 
 namespace Vit.Linq.MsTest.QueryBuilder.QueryableTest
 {
@@ -21,9 +21,9 @@ namespace Vit.Linq.MsTest.QueryBuilder.QueryableTest
             return Json.Deserialize<FilterRule_Newtonsoft>(filterRule);
         }
 
-        public override QueryBuilderService GetService()
+        public override FilterService GetService()
         {
-            QueryBuilderService service = new QueryBuilderService();
+            FilterService service = new FilterService();
             return service;
         }
 

+ 4 - 4
src/Test/Vit.Linq.MsTest/QueryBuilder/QueryableTest/Filter_Test_Newtonsoft2.cs → src/Test/Vit.Linq.MsTest/Filter/QueryableTest/Filter_Test_Newtonsoft2.cs

@@ -1,7 +1,7 @@
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 
-using Vit.Linq.QueryBuilder;
-using Vit.Linq.QueryBuilder.NewtonsoftJson;
+using Vit.Linq.Filter;
+using Vit.Linq.NewtonsoftJson;
 
 namespace Vit.Linq.MsTest.QueryBuilder.QueryableTest
 {
@@ -18,9 +18,9 @@ namespace Vit.Linq.MsTest.QueryBuilder.QueryableTest
         {
             return FilterRule_Newtonsoft.FromString(filterRule);
         }
-        public override QueryBuilderService GetService()
+        public override FilterService GetService()
         {
-            QueryBuilderService service = new QueryBuilderService();
+            FilterService service = new FilterService();
             return service;
         }
 

+ 4 - 4
src/Test/Vit.Linq.MsTest/QueryBuilder/QueryableTest/Filter_Test_SystemTextJson.cs → src/Test/Vit.Linq.MsTest/Filter/QueryableTest/Filter_Test_SystemTextJson.cs

@@ -2,8 +2,8 @@
 
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 
-using Vit.Linq.QueryBuilder;
-using Vit.Linq.QueryBuilder.SystemTextJson;
+using Vit.Linq.Filter;
+using Vit.Linq.SystemTextJson;
 
 namespace Vit.Linq.MsTest.QueryBuilder.QueryableTest
 {
@@ -21,9 +21,9 @@ namespace Vit.Linq.MsTest.QueryBuilder.QueryableTest
             return JsonSerializer.Deserialize<FilterRule_SystemTextJson>(filterRule);
         }
 
-        public override QueryBuilderService GetService()
+        public override FilterService GetService()
         {
-            QueryBuilderService service = new QueryBuilderService();
+            FilterService service = new FilterService();
             return service;
         }
 

+ 4 - 4
src/Test/Vit.Linq.MsTest/QueryBuilder/QueryableTest/Filter_Test_SystemTextJson2.cs → src/Test/Vit.Linq.MsTest/Filter/QueryableTest/Filter_Test_SystemTextJson2.cs

@@ -1,7 +1,7 @@
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 
-using Vit.Linq.QueryBuilder;
-using Vit.Linq.QueryBuilder.SystemTextJson;
+using Vit.Linq.Filter;
+using Vit.Linq.SystemTextJson;
 
 namespace Vit.Linq.MsTest.QueryBuilder.QueryableTest
 {
@@ -20,9 +20,9 @@ namespace Vit.Linq.MsTest.QueryBuilder.QueryableTest
             return FilterRule_SystemTextJson.FromString(filterRule);
         }
 
-        public override QueryBuilderService GetService()
+        public override FilterService GetService()
         {
-            QueryBuilderService service = new QueryBuilderService();
+            FilterService service = new FilterService();
             return service;
         }
     }

+ 1 - 1
src/Test/Vit.Linq.MsTest31/Vit.Linq.MsTest31.csproj

@@ -20,7 +20,7 @@
 
     <ItemGroup>
         <Compile Include="..\Vit.Linq.MsTest\Extensions\*.cs" Link="Extensions\%(RecursiveDir)%(FileName)%(Extension)" />
-        <Compile Include="..\Vit.Linq.MsTest\QueryBuilder\**\*.cs" Link="QueryBuilder\%(RecursiveDir)%(FileName)%(Extension)" />
+        <Compile Include="..\Vit.Linq.MsTest\Filter\**\*.cs" Link="Filter\%(RecursiveDir)%(FileName)%(Extension)" />
         <Compile Include="..\Vit.Linq.MsTest\DataSource.cs" />
     </ItemGroup>
 

+ 1 - 1
src/Vit.Linq.Extensions/Extensions/IQueryable_Sort_Extensions.cs

@@ -5,7 +5,7 @@ using System.Linq.Expressions;
 using System.Runtime.CompilerServices;
 
 using Vit.Core.Util.ComponentModel.Query;
-using Vit.Linq.QueryBuilder;
+using Vit.Linq;
 
 namespace Vit.Extensions.Linq_Extensions
 {

+ 2 - 3
src/Vit.Linq.Extensions/Extensions/Queryable_Sort_ByReflection_Extensions.cs

@@ -1,10 +1,9 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
 using System.Linq;
 using System.Runtime.CompilerServices;
 
 using Vit.Core.Util.ComponentModel.Query;
-using Vit.Linq.QueryBuilder;
+using Vit.Linq;
 
 namespace Vit.Extensions.Linq_Extensions
 {

+ 2 - 1
src/Vit.Linq.Extensions/Extensions/Queryable_Sort_Extensions.cs

@@ -5,7 +5,8 @@ using System.Reflection;
 using System.Runtime.CompilerServices;
 
 using Vit.Core.Util.ComponentModel.Query;
-using Vit.Linq.QueryBuilder;
+using Vit.Linq;
+using Vit.Linq.Filter;
 
 namespace Vit.Extensions.Linq_Extensions
 {

+ 1 - 1
src/Vit.Linq.NewtonsoftJson/FilterRule_Newtonsoft.cs

@@ -7,7 +7,7 @@ using Newtonsoft.Json.Linq;
 
 using Vit.Linq.MoreFilter;
 
-namespace Vit.Linq.QueryBuilder.NewtonsoftJson
+namespace Vit.Linq.NewtonsoftJson
 {
     /// <summary>
     /// This class is used to define a hierarchical filter for a given collection. This type can be serialized/deserialized by JSON.NET without needing to modify the data structure from QueryBuilder.

+ 1 - 1
src/Vit.Linq.SystemTextJson/FilterRule_SystemTextJson.cs

@@ -7,7 +7,7 @@ using System.Text.Unicode;
 
 using Vit.Linq.MoreFilter;
 
-namespace Vit.Linq.QueryBuilder.SystemTextJson
+namespace Vit.Linq.SystemTextJson
 {
     /// <summary>
     /// This class is used to define a hierarchical filter for a given collection. This type can be serialized/deserialized by JSON.NET without needing to modify the data structure from QueryBuilder.

+ 1 - 1
src/Vit.Linq/QueryBuilder/ECondition.cs → src/Vit.Linq/Filter/ECondition.cs

@@ -1,4 +1,4 @@
-namespace Vit.Linq.QueryBuilder
+namespace Vit.Linq.Filter
 {
     public enum ECondition
     {

+ 3 - 3
src/Vit.Linq/QueryBuilder/Extensions/IQueryable_Where_Extensions.cs → src/Vit.Linq/Filter/Extensions/IQueryable_Where_Extensions.cs

@@ -3,7 +3,7 @@ using System.Linq;
 using System.Linq.Expressions;
 using System.Runtime.CompilerServices;
 
-using Vit.Linq.QueryBuilder;
+using Vit.Linq.Filter;
 
 namespace Vit.Extensions.Linq_Extensions
 {
@@ -12,9 +12,9 @@ namespace Vit.Extensions.Linq_Extensions
         #region Where
 
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public static IQueryable IQueryable_Where(this IQueryable query, IFilterRule rule, QueryBuilderService service = null)
+        public static IQueryable IQueryable_Where(this IQueryable query, IFilterRule rule, FilterService service = null)
         {
-            LambdaExpression lambda = (service ?? QueryBuilderService.Instance).ToLambdaExpression(rule, query.ElementType);
+            LambdaExpression lambda = (service ?? FilterService.Instance).ToLambdaExpression(rule, query.ElementType);
             if (lambda == null) return query;
             return query.Provider.CreateQuery(
                 Expression.Call(

+ 3 - 3
src/Vit.Linq/QueryBuilder/Extensions/Queryable_Where_Extensions.cs → src/Vit.Linq/Filter/Extensions/Queryable_Where_Extensions.cs

@@ -1,7 +1,7 @@
 using System.Linq;
 using System.Runtime.CompilerServices;
 
-using Vit.Linq.QueryBuilder;
+using Vit.Linq.Filter;
 
 namespace Vit.Extensions.Linq_Extensions
 {
@@ -9,12 +9,12 @@ namespace Vit.Extensions.Linq_Extensions
     {
         #region Where
         [MethodImpl(MethodImplOptions.AggressiveInlining)]
-        public static IQueryable<T> Where<T>(this IQueryable<T> query, IFilterRule rule, QueryBuilderService service = null)
+        public static IQueryable<T> Where<T>(this IQueryable<T> query, IFilterRule rule, FilterService service = null)
         where T : class
         {
             if (query == null || rule == null) return query;
 
-            var predicate = (service ?? QueryBuilderService.Instance).ToExpression<T>(rule);
+            var predicate = (service ?? FilterService.Instance).ToExpression<T>(rule);
             if (predicate == null)
             {
                 return query;

+ 1 - 1
src/Vit.Linq/QueryBuilder/FilterRule.cs → src/Vit.Linq/Filter/FilterRule.cs

@@ -1,7 +1,7 @@
 using System.Collections.Generic;
 using System.Diagnostics.CodeAnalysis;
 
-namespace Vit.Linq.QueryBuilder
+namespace Vit.Linq.Filter
 {
     /// <summary>
     /// This class is used to define a hierarchical filter for a given collection. This type can be serialized/deserialized by JSON.NET without needing to modify the data structure from QueryBuilder.

+ 1 - 1
src/Vit.Linq/QueryBuilder/FilterRuleBase.cs → src/Vit.Linq/Filter/FilterRuleBase.cs

@@ -4,7 +4,7 @@ using System.Diagnostics.CodeAnalysis;
 using System.Linq;
 using System.Linq.Expressions;
 
-namespace Vit.Linq.QueryBuilder
+namespace Vit.Linq.Filter
 {
     /// <summary>
     /// This class is used to define a hierarchical filter for a given collection. This type can be serialized/deserialized by JSON.NET without needing to modify the data structure from QueryBuilder.

+ 1 - 1
src/Vit.Linq/QueryBuilder/FilterRuleOperator.cs → src/Vit.Linq/Filter/FilterRuleOperator.cs

@@ -1,4 +1,4 @@
-namespace Vit.Linq.QueryBuilder
+namespace Vit.Linq.Filter
 {
     public class FilterRuleOperator
     {

+ 364 - 0
src/Vit.Linq/Filter/FilterService.cs

@@ -0,0 +1,364 @@
+using System;
+using System.Collections;
+using System.Collections.Generic;
+using System.Linq;
+using System.Linq.Expressions;
+
+
+namespace Vit.Linq.Filter
+{
+    public class FilterService
+    {
+        public static FilterService Instance = new FilterService();
+
+        /// <summary>
+        /// operatorName -> operatorType(in class FilterRuleOperator)
+        /// </summary>
+        public Dictionary<string, string> operatorMap = new Dictionary<string, string>();
+        public bool operatorIsIgnoreCase = true;
+        public bool ignoreError = false;
+
+        public FilterService AddOperatorMap(string operatorName, string operatorType)
+        {
+            if (operatorIsIgnoreCase) operatorName = operatorName?.ToLower();
+            operatorMap[operatorName] = operatorType;
+            return this;
+        }
+
+        public FilterService AddOperatorMap(IEnumerable<(string operatorName, string operatorType)> maps)
+        {
+            foreach (var map in maps)
+                AddOperatorMap(map.operatorName, map.operatorType);
+            return this;
+        }
+
+
+
+        public Func<T, bool> ToPredicate<T>(IFilterRule rule)
+        {
+            return ToExpression<T>(rule)?.Compile();
+        }
+
+        public string ToExpressionString<T>(IFilterRule rule)
+        {
+            return ToExpression<T>(rule)?.ToString();
+        }
+
+
+        public Expression<Func<T, bool>> ToExpression<T>(IFilterRule rule)
+        {
+            var exp = ToLambdaExpression(rule, typeof(T));
+            return (Expression<Func<T, bool>>)exp;
+        }
+
+
+        public LambdaExpression ToLambdaExpression(IFilterRule rule, Type targetType)
+        {
+            ParameterExpression parameter = Expression.Parameter(targetType);
+            var expression = ConvertToExpression(rule, parameter);
+            if (expression == null)
+            {
+                return null;
+            }
+            return Expression.Lambda(expression, parameter);
+        }
+
+
+        public virtual ECondition GetCondition(IFilterRule filter)
+        {
+            return filter.condition?.ToLower() == "or" ? ECondition.or : ECondition.and;
+        }
+
+
+
+        protected virtual Expression GetLeftValueExpression(IFilterRule rule, ParameterExpression valueExpression)
+        {
+            return rule.GetLeftValueExpression(valueExpression); 
+        }
+
+
+        public virtual string GetOperator(IFilterRule filter)
+        {
+            var operate = filter.@operator ?? "";
+            if (operatorIsIgnoreCase) operate = operate.ToLower();
+            if (operatorMap.TryGetValue(operate, out var op2)) return operatorIsIgnoreCase ? op2?.ToLower() : op2;
+            return operate;
+        }
+
+
+        #region GetRightValueExpression
+
+        public Func<object, IFilterRule, Type, object> GetRuleValue { get; set; }
+        protected virtual object GetRulePrimitiveValue(object value, IFilterRule rule, Type fieldType)
+        {
+            if (GetRuleValue != null) return GetRuleValue(value, rule, fieldType);
+            return value;
+        }
+
+
+
+
+        protected virtual Expression GetRightValueExpression(IFilterRule rule, ParameterExpression parameter, Type valueType)
+        {
+            object rightValue = rule.value;
+
+            // typeof(IEnumerable).IsAssignableFrom(valueType)
+            if (valueType.IsGenericType && typeof(IEnumerable<>).IsAssignableFrom(valueType.GetGenericTypeDefinition()))
+            {
+                // constant List
+                object value = null;
+                if (rule.value != null)
+                {
+                    //value = Vit.Core.Module.Serialization.Json.Deserialize(Vit.Core.Module.Serialization.Json.Serialize(rule.value), valueType);
+                    var leftFieldType = valueType.GetGenericArguments()[0];
+                    value = ConvertToList(rule.value, rule, leftFieldType);
+                }
+                rightValue = value;
+            }
+            else
+            {
+                // constant value
+                object value = GetRulePrimitiveValue(rule.value, rule, valueType);
+                if (value != null)
+                {
+                    Type type = Nullable.GetUnderlyingType(valueType) ?? valueType;
+                    value = Convert.ChangeType(value, type);
+                }
+                rightValue = value;
+            }
+
+            Expression<Func<object>> valueLamba = () => rightValue;
+            return Expression.Convert(valueLamba.Body, valueType);
+        }
+
+        #region ConvertToList
+        internal object ConvertToList(object value, IFilterRule rule, Type fieldType)
+        {
+            if (value is string str)
+            {
+                var itemValue = GetRulePrimitiveValue(str, rule, fieldType);
+                if (itemValue is IEnumerable)
+                    return itemValue;
+            }
+            else if (value is IEnumerable values)
+            {
+                var methodInfo = typeof(FilterService).GetMethod("ConvertToListByType", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).MakeGenericMethod(fieldType);
+                return methodInfo.Invoke(this, new object[] { values, rule });
+            }
+            return null;
+        }
+        internal List<T> ConvertToListByType<T>(IEnumerable values, IFilterRule rule)
+        {
+            Type fieldType = typeof(T);
+            var list = new List<T>();
+            foreach (var item in values)
+            {
+                var itemValue = GetRulePrimitiveValue(item, rule, fieldType);
+                T value = (T)Convert.ChangeType(itemValue, fieldType);
+                list.Add(value);
+            }
+            return list;
+        }
+        #endregion
+
+        #endregion
+
+
+        Expression ConvertToExpression(IFilterRule rule, ParameterExpression parameter)
+        {
+            if (rule == null) return null;
+
+            // #1 nested filter rules
+            if (rule.rules?.Any() == true)
+            {
+                return ConvertToExpression(rule.rules, parameter, GetCondition(rule));
+            }
+
+            // #2 simple rule
+            if (string.IsNullOrWhiteSpace(rule.@operator))
+            {
+                return null;
+            }
+
+            Expression leftValueExpression = GetLeftValueExpression(rule, parameter);
+            Type leftFieldType = leftValueExpression.Type;
+
+            #region Get Expression
+
+            var Operator = GetOperator(rule);
+            var cmpType = operatorIsIgnoreCase ? StringComparison.OrdinalIgnoreCase : StringComparison.Ordinal;
+
+
+            {
+                #region ##1  null
+                if (FilterRuleOperator.IsNull.Equals(Operator, cmpType))
+                {
+                    return IsNull();
+                }
+                if (FilterRuleOperator.IsNotNull.Equals(Operator, cmpType))
+                {
+                    return Expression.Not(IsNull());
+                }
+                #endregion
+
+
+                #region ##2 number
+                if (FilterRuleOperator.Equal.Equals(Operator, cmpType))
+                {
+                    return Expression.Equal(leftValueExpression, GetRightValueExpression());
+                }
+                if (FilterRuleOperator.NotEqual.Equals(Operator, cmpType))
+                {
+                    return Expression.NotEqual(leftValueExpression, GetRightValueExpression());
+                }
+
+                if (FilterRuleOperator.GreaterThan.Equals(Operator, cmpType))
+                {
+                    return Expression.GreaterThan(leftValueExpression, GetRightValueExpression());
+                }
+                if (FilterRuleOperator.GreaterThanOrEqual.Equals(Operator, cmpType))
+                {
+                    return Expression.GreaterThanOrEqual(leftValueExpression, GetRightValueExpression());
+                }
+                if (FilterRuleOperator.LessThan.Equals(Operator, cmpType))
+                {
+                    return Expression.LessThan(leftValueExpression, GetRightValueExpression());
+
+                }
+                if (FilterRuleOperator.LessThanOrEqual.Equals(Operator, cmpType))
+                {
+                    return Expression.LessThanOrEqual(leftValueExpression, GetRightValueExpression());
+                }
+                #endregion
+
+
+                #region ##3 array
+                if (FilterRuleOperator.In.Equals(Operator, cmpType))
+                {
+                    return In();
+                }
+                if (FilterRuleOperator.NotIn.Equals(Operator, cmpType))
+                {
+                    return Expression.Not(In());
+                }
+                #endregion
+
+
+                #region ##4 string
+                if (FilterRuleOperator.Contains.Equals(Operator, cmpType))
+                {
+                    var nullCheck = Expression.Call(typeof(string), "IsNullOrEmpty", null, leftValueExpression);
+                    var contains = Expression.Call(leftValueExpression, "Contains", null, GetRightValueExpression());
+
+                    return Expression.AndAlso(Expression.Not(nullCheck), contains);
+
+                }
+                if (FilterRuleOperator.NotContains.Equals(Operator, cmpType))
+                {
+                    var nullCheck = Expression.Call(typeof(string), "IsNullOrEmpty", null, leftValueExpression);
+                    var contains = Expression.Call(leftValueExpression, "Contains", null, GetRightValueExpression());
+
+                    return Expression.OrElse(nullCheck, Expression.Not(contains));
+                }
+                if (FilterRuleOperator.StartsWith.Equals(Operator, cmpType))
+                {
+                    var nullCheck = Expression.Not(Expression.Call(typeof(string), "IsNullOrEmpty", null, leftValueExpression));
+                    var startsWith = Expression.Call(leftValueExpression, "StartsWith", null, GetRightValueExpression());
+
+                    return Expression.AndAlso(nullCheck, startsWith);
+                }
+
+                if (FilterRuleOperator.EndsWith.Equals(Operator, cmpType))
+                {
+                    var nullCheck = Expression.Not(Expression.Call(typeof(string), "IsNullOrEmpty", null, leftValueExpression));
+                    var endsWith = Expression.Call(leftValueExpression, "EndsWith", null, GetRightValueExpression());
+                    return Expression.AndAlso(nullCheck, endsWith);
+                }
+                if (FilterRuleOperator.IsNullOrEmpty.Equals(Operator, cmpType))
+                {
+                    return Expression.Call(typeof(string), "IsNullOrEmpty", null, leftValueExpression);
+                }
+                if (FilterRuleOperator.IsNotNullOrEmpty.Equals(Operator, cmpType))
+                {
+                    return Expression.Not(Expression.Call(typeof(string), "IsNullOrEmpty", null, leftValueExpression));
+                }
+                #endregion
+
+            }
+            #endregion
+
+            if (!ignoreError) throw new Exception("unrecognized operator : " + rule.@operator);
+            return null;
+
+
+            #region inner Method
+            Expression GetRightValueExpression()
+            {
+                return this.GetRightValueExpression(rule, parameter, leftFieldType);
+            }
+
+            Expression IsNull()
+            {
+                var isNullable = !leftFieldType.IsValueType || Nullable.GetUnderlyingType(leftFieldType) != null;
+
+                if (isNullable)
+                {
+                    var nullValue = Expression.Constant(null, leftFieldType);
+                    return Expression.Equal(leftValueExpression, nullValue);
+                }
+                return Expression.Constant(false, typeof(bool));
+            }
+
+            Expression In()
+            {
+                Expression arrayExp = null;
+                Type valueType = typeof(IEnumerable<>).MakeGenericType(leftFieldType);
+                arrayExp = this.GetRightValueExpression(rule, parameter, valueType);
+
+                var inCheck = Expression.Call(typeof(System.Linq.Enumerable), "Contains", new[] { leftFieldType }, arrayExp, leftValueExpression);
+                return inCheck;
+            }
+            #endregion
+        }
+
+
+        Expression ConvertToExpression(IEnumerable<IFilterRule> rules, ParameterExpression parameter, ECondition condition = ECondition.and)
+        {
+            if (rules?.Any() != true)
+            {
+                return null;
+            }
+
+            Expression expression = null;
+
+            foreach (var rule in rules)
+            {
+                var curExp = ConvertToExpression(rule, parameter);
+                if (curExp != null)
+                    expression = Append(expression, curExp);
+            }
+
+            return expression;
+
+
+            #region Method Append
+            Expression Append(Expression exp1, Expression exp2)
+            {
+                if (exp1 == null)
+                {
+                    return exp2;
+                }
+
+                if (exp2 == null)
+                {
+                    return exp1;
+                }
+                return condition == ECondition.or ? Expression.OrElse(exp1, exp2) : Expression.AndAlso(exp1, exp2);
+            }
+            #endregion
+
+        }
+
+
+    }
+}

+ 1 - 1
src/Vit.Linq/QueryBuilder/IFilterRule.cs → src/Vit.Linq/Filter/IFilterRule.cs

@@ -2,7 +2,7 @@
 using System.Collections.Generic;
 using System.Linq.Expressions;
 
-namespace Vit.Linq.QueryBuilder
+namespace Vit.Linq.Filter
 {
     /// <summary>
     /// This interface is used to define a hierarchical filter for a given collection.

+ 0 - 0
src/Vit.Linq/QueryBuilder/QueryBuilderService.cs → src/Vit.Linq/Filter/QueryBuilderService.cs


+ 1 - 1
src/Vit.Linq/LinqHelp.Reflection.cs

@@ -2,7 +2,7 @@
 using System.Linq.Expressions;
 using System.Reflection;
 
-namespace Vit.Linq.QueryBuilder
+namespace Vit.Linq
 {
     public partial class LinqHelp
     {

+ 1 - 2
src/Vit.Linq/LinqHelp.cs

@@ -1,10 +1,9 @@
 using System;
 using System.Collections;
-using System.Collections.Generic;
 using System.Linq;
 using System.Linq.Expressions;
 
-namespace Vit.Linq.QueryBuilder
+namespace Vit.Linq
 {
     public partial class LinqHelp
     {

+ 1 - 1
src/Vit.Linq/MoreFilter/FilterRuleWithMethod.cs

@@ -3,7 +3,7 @@ using System.Collections.Generic;
 using System.Diagnostics.CodeAnalysis;
 using System.Linq.Expressions;
 using System.Linq;
-using Vit.Linq.QueryBuilder;
+using Vit.Linq.Filter;
 
 namespace Vit.Linq.MoreFilter
 {

+ 0 - 3
src/Vit.Linq/readme.md

@@ -1,3 +0,0 @@
-ref https://www.cnblogs.com/seriawei/p/entity-framework-dynamic-search.html 
-
-ref DynamicQueryable