mirror of
https://github.com/Biarity/Sieve.git
synced 2024-11-22 05:22:57 +01:00
implement ability to filter int values using string operators
This commit is contained in:
parent
b73f748dba
commit
22dae2eaf7
@ -202,13 +202,8 @@ namespace Sieve.Services
|
||||
|
||||
if (filterTerm.OperatorIsCaseInsensitive && !isFilterTermValueNull)
|
||||
{
|
||||
propertyValue = Expression.Call(propertyValue,
|
||||
typeof(string).GetMethods()
|
||||
.First(m => m.Name == "ToUpper" && m.GetParameters().Length == 0));
|
||||
|
||||
filterValue = Expression.Call(filterValue,
|
||||
typeof(string).GetMethods()
|
||||
.First(m => m.Name == "ToUpper" && m.GetParameters().Length == 0));
|
||||
propertyValue = GetStringMethodExpression(propertyValue, "ToUpper");
|
||||
filterValue = GetStringMethodExpression(filterValue, "ToUpper");
|
||||
}
|
||||
|
||||
var expression = GetExpression(filterTerm, filterValue, propertyValue);
|
||||
@ -333,19 +328,30 @@ namespace Sieve.Services
|
||||
FilterOperator.LessThan => Expression.LessThan(propertyValue, filterValue),
|
||||
FilterOperator.GreaterThanOrEqualTo => Expression.GreaterThanOrEqual(propertyValue, filterValue),
|
||||
FilterOperator.LessThanOrEqualTo => Expression.LessThanOrEqual(propertyValue, filterValue),
|
||||
FilterOperator.Contains => Expression.Call(propertyValue,
|
||||
typeof(string).GetMethods().First(m => m.Name == "Contains" && m.GetParameters().Length == 1),
|
||||
filterValue),
|
||||
FilterOperator.StartsWith => Expression.Call(propertyValue,
|
||||
typeof(string).GetMethods().First(m => m.Name == "StartsWith" && m.GetParameters().Length == 1),
|
||||
filterValue),
|
||||
FilterOperator.EndsWith => Expression.Call(propertyValue,
|
||||
typeof(string).GetMethods().First(m => m.Name == "EndsWith" && m.GetParameters().Length == 1),
|
||||
filterValue),
|
||||
FilterOperator.Contains => GetStringMethodExpression(filterValue, propertyValue, "Contains"),
|
||||
FilterOperator.StartsWith => GetStringMethodExpression(filterValue, propertyValue, "StartsWith"),
|
||||
FilterOperator.EndsWith => GetStringMethodExpression(filterValue, propertyValue, "EndsWith"),
|
||||
_ => Expression.Equal(propertyValue, filterValue)
|
||||
};
|
||||
}
|
||||
|
||||
private static Expression GetStringMethodExpression(dynamic filterValue, dynamic propertyValue, string methodName) =>
|
||||
propertyValue.Type == typeof(string) && filterValue.Type == typeof(string)
|
||||
? Expression.Call(propertyValue, GetStringMethod(methodName, 1), filterValue)
|
||||
: Expression.Call(CallToString(propertyValue), GetStringMethod(methodName, 1), CallToString(filterValue));
|
||||
|
||||
private static Expression GetStringMethodExpression(dynamic propertyValue, string methodName) =>
|
||||
propertyValue.Type == typeof(string)
|
||||
? Expression.Call(propertyValue, GetStringMethod(methodName, 0))
|
||||
: Expression.Call(CallToString(propertyValue), GetStringMethod(methodName, 0));
|
||||
|
||||
private static Expression CallToString(dynamic value) =>
|
||||
Expression.Call(value, typeof(object).GetMethod("ToString"));
|
||||
|
||||
private static MethodInfo GetStringMethod(string methodName, int paramCount) =>
|
||||
typeof(string).GetMethods()
|
||||
.First(m => m.Name == methodName && m.GetParameters().Length == paramCount);
|
||||
|
||||
// Workaround to ensure that the filter value gets passed as a parameter in generated SQL from EF Core
|
||||
private static Expression GetClosureOverConstant<T>(T constant, Type targetType)
|
||||
{
|
||||
|
@ -39,7 +39,7 @@ namespace SieveUnitTests
|
||||
{
|
||||
Id = 0,
|
||||
Title = "A",
|
||||
LikeCount = 100,
|
||||
LikeCount = 500,
|
||||
IsDraft = true,
|
||||
CategoryId = null,
|
||||
TopComment = new Comment { Id = 0, Text = "A1" },
|
||||
@ -255,6 +255,108 @@ namespace SieveUnitTests
|
||||
Assert.True(nullableResult.Count() == 3);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(5)]
|
||||
[InlineData(0)]
|
||||
public void CanFilterIntsUsingContainsOperator(int likeCount)
|
||||
{
|
||||
var model = new SieveModel
|
||||
{
|
||||
Filters = $"LikeCount@={likeCount}"
|
||||
};
|
||||
|
||||
var result = _processor.Apply(model, _posts);
|
||||
|
||||
Assert.True(result.Count() == 3);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(5)]
|
||||
[InlineData(0)]
|
||||
public void CanFilterIntsUsingCaseInsensitiveContainsOperator(int likeCount)
|
||||
{
|
||||
var model = new SieveModel
|
||||
{
|
||||
Filters = $"LikeCount@=*{likeCount}"
|
||||
};
|
||||
|
||||
var result = _processor.Apply(model, _posts);
|
||||
|
||||
Assert.True(result.Count() == 3);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(5)]
|
||||
[InlineData(0)]
|
||||
public void CanFilterIntsUsingDoesNotContainsOperator(int likeCount)
|
||||
{
|
||||
var model = new SieveModel
|
||||
{
|
||||
Filters = $"LikeCount!@={likeCount}"
|
||||
};
|
||||
|
||||
var result = _processor.Apply(model, _posts);
|
||||
|
||||
Assert.True(result.Count() == 2);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(5)]
|
||||
[InlineData(0)]
|
||||
public void CanFilterIntsUsingCaseInsensitiveDoesNotContainsOperator(int likeCount)
|
||||
{
|
||||
var model = new SieveModel
|
||||
{
|
||||
Filters = $"LikeCount!@=*{likeCount}"
|
||||
};
|
||||
|
||||
var result = _processor.Apply(model, _posts);
|
||||
|
||||
Assert.True(result.Count() == 2);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(5)]
|
||||
public void CanFilterIntsUsingCaseInsensitiveDoesNotStartsWithOperator(int likeCount)
|
||||
{
|
||||
var model = new SieveModel
|
||||
{
|
||||
Filters = $"LikeCount!_=*{likeCount}"
|
||||
};
|
||||
|
||||
var result = _processor.Apply(model, _posts);
|
||||
|
||||
Assert.True(result.Count() == 2);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(5)]
|
||||
public void CanFilterIntsUsingStartsWithOperator(int likeCount)
|
||||
{
|
||||
var model = new SieveModel
|
||||
{
|
||||
Filters = $"LikeCount_={likeCount}"
|
||||
};
|
||||
|
||||
var result = _processor.Apply(model, _posts);
|
||||
|
||||
Assert.True(result.Count() == 3);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(0)]
|
||||
public void CanFilterIntsUsingEndsWithOperator(int likeCount)
|
||||
{
|
||||
var model = new SieveModel
|
||||
{
|
||||
Filters = $"LikeCount_-={likeCount}"
|
||||
};
|
||||
|
||||
var result = _processor.Apply(model, _posts);
|
||||
|
||||
Assert.True(result.Count() == 3);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[InlineData(@"Text@=*\,")]
|
||||
[InlineData(@"Text@=*\, ")]
|
||||
|
Loading…
Reference in New Issue
Block a user