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="ComplexQueriesTests.cs" />
|
||||||
<Compile Include="ConstantTests.cs" />
|
<Compile Include="ConstantTests.cs" />
|
||||||
<Compile Include="Helpers\QueryableAssert.cs" />
|
<Compile Include="Helpers\QueryableAssert.cs" />
|
||||||
|
<Compile Include="InTests.cs" />
|
||||||
<Compile Include="ShortcutTests.cs" />
|
<Compile Include="ShortcutTests.cs" />
|
||||||
<Compile Include="SimpleQueriesTest.cs" />
|
<Compile Include="SimpleQueriesTest.cs" />
|
||||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
@ -17,7 +17,9 @@ namespace PoweredSoft.DynamicLinq
|
|||||||
LessThanOrEqual,
|
LessThanOrEqual,
|
||||||
Contains,
|
Contains,
|
||||||
StartsWith,
|
StartsWith,
|
||||||
EndsWith
|
EndsWith,
|
||||||
|
In,
|
||||||
|
NotIn
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum QueryConvertStrategy
|
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)
|
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);
|
=> Or(path, ConditionOperators.EndsWith, value, convertStrategy: convertStrategy, collectionHandling: collectionHandling, stringComparision: stringComparision);
|
||||||
#endregion
|
#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;
|
||||||
|
using System.Collections;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Linq.Expressions;
|
using System.Linq.Expressions;
|
||||||
@ -151,6 +152,17 @@ namespace PoweredSoft.DynamicLinq.Helpers
|
|||||||
return query;
|
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,
|
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)
|
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.
|
// create the expression and return it.
|
||||||
if (isLast)
|
if (isLast)
|
||||||
{
|
{
|
||||||
var constant = QueryableHelpers.ResolveConstant(memberExpression, value, convertStrategy);
|
if (condition == ConditionOperators.In || condition == ConditionOperators.NotIn)
|
||||||
var filterExpression = QueryableHelpers.GetConditionExpressionForMember(parameter, memberExpression, condition, constant, stringComparison);
|
{
|
||||||
var lambda = Expression.Lambda(filterExpression, parameter);
|
return InAndNotIn(parameter, condition, value, convertStrategy, memberExpression);
|
||||||
return lambda;
|
}
|
||||||
|
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.
|
// 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)
|
public static MethodInfo GetCollectionMethod(QueryCollectionHandling collectionHandling)
|
||||||
{
|
{
|
||||||
if (collectionHandling == QueryCollectionHandling.All)
|
if (collectionHandling == QueryCollectionHandling.All)
|
||||||
|
Loading…
Reference in New Issue
Block a user