supporting in and not in.
This commit is contained in:
		
							parent
							
								
									47f31d5b74
								
							
						
					
					
						commit
						60dedaecf4
					
				
							
								
								
									
										65
									
								
								PoweredSoft.DynamicLinq.Test/InTests.cs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										65
									
								
								PoweredSoft.DynamicLinq.Test/InTests.cs
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,65 @@ | ||||
| using System; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using Microsoft.VisualStudio.TestTools.UnitTesting; | ||||
| using PoweredSoft.DynamicLinq; | ||||
| using PoweredSoft.DynamicLinq.Test.Helpers; | ||||
| 
 | ||||
| namespace PoweredSoft.DynamicLinq.Test | ||||
| { | ||||
|     [TestClass] | ||||
|     public class InTests | ||||
|     { | ||||
|         internal List<MockPersonObject> Persons = new List<MockPersonObject> | ||||
|         { | ||||
|             new MockPersonObject { FirstName = "David", LastName = "Lebee", Age = 28 }, | ||||
|             new MockPersonObject { FirstName = "Michaela", LastName = "Vickar", Age = 27 }, | ||||
|             new MockPersonObject { FirstName = "John", LastName = "Doe", Age = 28 }, | ||||
|             new MockPersonObject { FirstName = "Chuck", LastName = "Norris", Age = 50 }, | ||||
|             new MockPersonObject { FirstName = "Michael", LastName = "Jackson", Age = 58 } | ||||
|         }; | ||||
| 
 | ||||
|         [TestMethod] | ||||
|         public void In() | ||||
|         { | ||||
|             IQueryable<MockPersonObject> a, b; | ||||
|             var ageGroup = new List<int>() { 28, 27, 50 }; | ||||
| 
 | ||||
|             a = Persons.AsQueryable().Query(t => t.In("Age", ageGroup)); | ||||
|             b = Persons.AsQueryable().Where(t => ageGroup.Contains(t.Age)); | ||||
|             QueryableAssert.AreEqual(a, b); | ||||
|         } | ||||
| 
 | ||||
|         [TestMethod] | ||||
|         public void NotIn() | ||||
|         { | ||||
|             IQueryable<MockPersonObject> a, b; | ||||
|             var ageGroup = new List<int>() { 50, 58 }; | ||||
|             a = Persons.AsQueryable().Query(t => t.NotIn("Age", ageGroup)); | ||||
|             b = Persons.AsQueryable().Where(t => !ageGroup.Contains(t.Age)); | ||||
|             QueryableAssert.AreEqual(a, b); | ||||
|         } | ||||
| 
 | ||||
|         [TestMethod] | ||||
|         public void InString() | ||||
|         { | ||||
|             IQueryable<MockPersonObject> a, b; | ||||
|             var group = new List<string>() { "David", "Michaela" }; | ||||
|             a = Persons.AsQueryable().Query(t => t.In("FirstName", group)); | ||||
|             b = Persons.AsQueryable().Where(t => group.Contains(t.FirstName)); | ||||
|             QueryableAssert.AreEqual(a, b); | ||||
|         } | ||||
| 
 | ||||
|         [TestMethod] | ||||
|         public void DiffTypeListConversion() | ||||
|         { | ||||
|             IQueryable<MockPersonObject> a, b; | ||||
|             var ageGroup = new List<string>() { "28", "27", "50" }; | ||||
|             var ageGroupInt = ageGroup.Select(t => Convert.ToInt32(t)).ToList(); | ||||
| 
 | ||||
|             a = Persons.AsQueryable().Query(t => t.In("Age", ageGroup)); | ||||
|             b = Persons.AsQueryable().Where(t => ageGroupInt.Contains(t.Age)); | ||||
|             QueryableAssert.AreEqual(a, b); | ||||
|         } | ||||
|     } | ||||
| } | ||||
| @ -63,6 +63,7 @@ | ||||
|     <Compile Include="ComplexQueriesTests.cs" /> | ||||
|     <Compile Include="ConstantTests.cs" /> | ||||
|     <Compile Include="Helpers\QueryableAssert.cs" /> | ||||
|     <Compile Include="InTests.cs" /> | ||||
|     <Compile Include="ShortcutTests.cs" /> | ||||
|     <Compile Include="SimpleQueriesTest.cs" /> | ||||
|     <Compile Include="Properties\AssemblyInfo.cs" /> | ||||
|  | ||||
| @ -17,7 +17,9 @@ namespace PoweredSoft.DynamicLinq | ||||
|         LessThanOrEqual, | ||||
|         Contains, | ||||
|         StartsWith, | ||||
|         EndsWith | ||||
|         EndsWith, | ||||
|         In, | ||||
|         NotIn | ||||
|     } | ||||
| 
 | ||||
|     public enum QueryConvertStrategy | ||||
|  | ||||
| @ -118,5 +118,27 @@ namespace PoweredSoft.DynamicLinq.Fluent | ||||
|         public QueryBuilderBase OrEndsWith(string path, object value, QueryConvertStrategy convertStrategy = QueryConvertStrategy.ConvertConstantToComparedPropertyOrField, QueryCollectionHandling collectionHandling = QueryCollectionHandling.Any, StringComparison? stringComparision = null) | ||||
|             => Or(path, ConditionOperators.EndsWith, value, convertStrategy: convertStrategy, collectionHandling: collectionHandling, stringComparision: stringComparision); | ||||
|         #endregion | ||||
| 
 | ||||
|         #region In | ||||
|         public QueryBuilderBase In(string path, object value, QueryConvertStrategy convertStrategy = QueryConvertStrategy.ConvertConstantToComparedPropertyOrField, QueryCollectionHandling collectionHandling = QueryCollectionHandling.Any, StringComparison? stringComparision = null) | ||||
|             => And(path, ConditionOperators.In, value, convertStrategy: convertStrategy, collectionHandling: collectionHandling, stringComparision: stringComparision); | ||||
| 
 | ||||
|         public QueryBuilderBase AndIn(string path, object value, QueryConvertStrategy convertStrategy = QueryConvertStrategy.ConvertConstantToComparedPropertyOrField, QueryCollectionHandling collectionHandling = QueryCollectionHandling.Any, StringComparison? stringComparision = null) | ||||
|             => And(path, ConditionOperators.In, value, convertStrategy: convertStrategy, collectionHandling: collectionHandling, stringComparision: stringComparision); | ||||
| 
 | ||||
|         public QueryBuilderBase OrIn(string path, object value, QueryConvertStrategy convertStrategy = QueryConvertStrategy.ConvertConstantToComparedPropertyOrField, QueryCollectionHandling collectionHandling = QueryCollectionHandling.Any, StringComparison? stringComparision = null) | ||||
|             => Or(path, ConditionOperators.In, value, convertStrategy: convertStrategy, collectionHandling: collectionHandling, stringComparision: stringComparision); | ||||
|         #endregion | ||||
| 
 | ||||
|         #region NotIn | ||||
|         public QueryBuilderBase NotIn(string path, object value, QueryConvertStrategy convertStrategy = QueryConvertStrategy.ConvertConstantToComparedPropertyOrField, QueryCollectionHandling collectionHandling = QueryCollectionHandling.Any, StringComparison? stringComparision = null) | ||||
|             => And(path, ConditionOperators.NotIn, value, convertStrategy: convertStrategy, collectionHandling: collectionHandling, stringComparision: stringComparision); | ||||
| 
 | ||||
|         public QueryBuilderBase AndNotIn(string path, object value, QueryConvertStrategy convertStrategy = QueryConvertStrategy.ConvertConstantToComparedPropertyOrField, QueryCollectionHandling collectionHandling = QueryCollectionHandling.Any, StringComparison? stringComparision = null) | ||||
|             => And(path, ConditionOperators.NotIn, value, convertStrategy: convertStrategy, collectionHandling: collectionHandling, stringComparision: stringComparision); | ||||
| 
 | ||||
|         public QueryBuilderBase OrNotIn(string path, object value, QueryConvertStrategy convertStrategy = QueryConvertStrategy.ConvertConstantToComparedPropertyOrField, QueryCollectionHandling collectionHandling = QueryCollectionHandling.Any, StringComparison? stringComparision = null) | ||||
|             => Or(path, ConditionOperators.NotIn, value, convertStrategy: convertStrategy, collectionHandling: collectionHandling, stringComparision: stringComparision); | ||||
|         #endregion | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -1,4 +1,5 @@ | ||||
| using System; | ||||
| using System.Collections; | ||||
| using System.Collections.Generic; | ||||
| using System.Linq; | ||||
| using System.Linq.Expressions; | ||||
| @ -151,6 +152,17 @@ namespace PoweredSoft.DynamicLinq.Helpers | ||||
|             return query; | ||||
|         } | ||||
| 
 | ||||
|         /* | ||||
|          * var methodInfo = typeof(List<Guid>).GetMethod("Contains", new Type[] { typeof(Guid) }); | ||||
|                 var list = Expression.Constant(ids); | ||||
|                 var param = Expression.Parameter(typeof(T), "t"); | ||||
|                 var value = Expression.PropertyOrField(param, idField); | ||||
|                 var body = Expression.Call(list, methodInfo, value); | ||||
|                 var lambda = Expression.Lambda<Func<T, bool>>(body, param); | ||||
|                 query = query.Where(lambda); | ||||
| 
 | ||||
|          */ | ||||
| 
 | ||||
|         internal static Expression InternalCreateFilterExpression(int recursionStep, Type type, ParameterExpression parameter, Expression current, List<string> parts, | ||||
|             ConditionOperators condition, object value, QueryConvertStrategy convertStrategy, QueryCollectionHandling collectionHandling, bool nullChecking, StringComparison? stringComparison) | ||||
|         { | ||||
| @ -169,10 +181,17 @@ namespace PoweredSoft.DynamicLinq.Helpers | ||||
|             // create the expression and return it. | ||||
|             if (isLast) | ||||
|             { | ||||
|                 var constant = QueryableHelpers.ResolveConstant(memberExpression, value, convertStrategy); | ||||
|                 var filterExpression = QueryableHelpers.GetConditionExpressionForMember(parameter, memberExpression, condition, constant, stringComparison); | ||||
|                 var lambda = Expression.Lambda(filterExpression, parameter); | ||||
|                 return lambda; | ||||
|                 if (condition == ConditionOperators.In || condition == ConditionOperators.NotIn) | ||||
|                 { | ||||
|                     return InAndNotIn(parameter, condition, value, convertStrategy, memberExpression); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
|                     var constant = QueryableHelpers.ResolveConstant(memberExpression, value, convertStrategy); | ||||
|                     var filterExpression = QueryableHelpers.GetConditionExpressionForMember(parameter, memberExpression, condition, constant, stringComparison); | ||||
|                     var lambda = Expression.Lambda(filterExpression, parameter); | ||||
|                     return lambda; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             // null check. | ||||
| @ -212,6 +231,42 @@ namespace PoweredSoft.DynamicLinq.Helpers | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public static Expression InAndNotIn(ParameterExpression parameter, ConditionOperators condition, object value, QueryConvertStrategy convertStrategy, MemberExpression memberExpression) | ||||
|         { | ||||
|             var enumerableValue = value as IEnumerable; | ||||
|             if (enumerableValue == null) | ||||
|                 throw new Exception($"to use {ConditionOperators.In} your value must at least be IEnumerable"); | ||||
| 
 | ||||
|             var enumerableType = GetEnumerableType(enumerableValue); | ||||
|             var finalType = convertStrategy == QueryConvertStrategy.ConvertConstantToComparedPropertyOrField ? memberExpression.Type : enumerableType; | ||||
|             var genericListOfEnumerableType = typeof(List<>).MakeGenericType(memberExpression.Type); | ||||
|             var containsMethod = genericListOfEnumerableType.GetMethod("Contains", new Type[] { finalType }); | ||||
|             var list = Activator.CreateInstance(genericListOfEnumerableType) as IList; | ||||
|             foreach (var o in enumerableValue) | ||||
|             { | ||||
|                 if (convertStrategy == QueryConvertStrategy.ConvertConstantToComparedPropertyOrField) | ||||
|                     list.Add(TypeHelpers.ConvertFrom(memberExpression.Type, o)); | ||||
|                 else | ||||
|                     list.Add(o); | ||||
|             } | ||||
| 
 | ||||
|             var body = Expression.Call(Expression.Constant(list), containsMethod, memberExpression) as Expression; | ||||
| 
 | ||||
|             if (condition == ConditionOperators.NotIn) | ||||
|                 body = Expression.Not(body); | ||||
| 
 | ||||
|             var lambda = Expression.Lambda(body, parameter); | ||||
|             return lambda; | ||||
|         } | ||||
| 
 | ||||
|         private static Type GetEnumerableType(IEnumerable enumerableValue) | ||||
|         { | ||||
|             foreach (var o in enumerableValue) | ||||
|                 return o.GetType(); | ||||
| 
 | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         public static MethodInfo GetCollectionMethod(QueryCollectionHandling collectionHandling) | ||||
|         { | ||||
|             if (collectionHandling == QueryCollectionHandling.All) | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user