mirror of
https://github.com/Biarity/Sieve.git
synced 2024-11-22 13:32:33 +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)
|
if (filterTerm.OperatorIsCaseInsensitive && !isFilterTermValueNull)
|
||||||
{
|
{
|
||||||
propertyValue = Expression.Call(propertyValue,
|
propertyValue = GetStringMethodExpression(propertyValue, "ToUpper");
|
||||||
typeof(string).GetMethods()
|
filterValue = GetStringMethodExpression(filterValue, "ToUpper");
|
||||||
.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));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var expression = GetExpression(filterTerm, filterValue, propertyValue);
|
var expression = GetExpression(filterTerm, filterValue, propertyValue);
|
||||||
@ -333,19 +328,30 @@ namespace Sieve.Services
|
|||||||
FilterOperator.LessThan => Expression.LessThan(propertyValue, filterValue),
|
FilterOperator.LessThan => Expression.LessThan(propertyValue, filterValue),
|
||||||
FilterOperator.GreaterThanOrEqualTo => Expression.GreaterThanOrEqual(propertyValue, filterValue),
|
FilterOperator.GreaterThanOrEqualTo => Expression.GreaterThanOrEqual(propertyValue, filterValue),
|
||||||
FilterOperator.LessThanOrEqualTo => Expression.LessThanOrEqual(propertyValue, filterValue),
|
FilterOperator.LessThanOrEqualTo => Expression.LessThanOrEqual(propertyValue, filterValue),
|
||||||
FilterOperator.Contains => Expression.Call(propertyValue,
|
FilterOperator.Contains => GetStringMethodExpression(filterValue, propertyValue, "Contains"),
|
||||||
typeof(string).GetMethods().First(m => m.Name == "Contains" && m.GetParameters().Length == 1),
|
FilterOperator.StartsWith => GetStringMethodExpression(filterValue, propertyValue, "StartsWith"),
|
||||||
filterValue),
|
FilterOperator.EndsWith => GetStringMethodExpression(filterValue, propertyValue, "EndsWith"),
|
||||||
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),
|
|
||||||
_ => Expression.Equal(propertyValue, filterValue)
|
_ => 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
|
// 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)
|
private static Expression GetClosureOverConstant<T>(T constant, Type targetType)
|
||||||
{
|
{
|
||||||
|
@ -39,7 +39,7 @@ namespace SieveUnitTests
|
|||||||
{
|
{
|
||||||
Id = 0,
|
Id = 0,
|
||||||
Title = "A",
|
Title = "A",
|
||||||
LikeCount = 100,
|
LikeCount = 500,
|
||||||
IsDraft = true,
|
IsDraft = true,
|
||||||
CategoryId = null,
|
CategoryId = null,
|
||||||
TopComment = new Comment { Id = 0, Text = "A1" },
|
TopComment = new Comment { Id = 0, Text = "A1" },
|
||||||
@ -255,6 +255,108 @@ namespace SieveUnitTests
|
|||||||
Assert.True(nullableResult.Count() == 3);
|
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]
|
[Theory]
|
||||||
[InlineData(@"Text@=*\,")]
|
[InlineData(@"Text@=*\,")]
|
||||||
[InlineData(@"Text@=*\, ")]
|
[InlineData(@"Text@=*\, ")]
|
||||||
|
Loading…
Reference in New Issue
Block a user