stop excluding null values when filtering using notEqual (#114)

* stop excluding null values when filtering using notEqual
* add IgnoreNullsOnNotEqual config field, to enable/disable the new feature

Co-authored-by: AnasZakarneh <a.zakarneh@foothillsolutions.com>
This commit is contained in:
AnasZakarneh 2021-05-24 20:24:18 +03:00 committed by GitHub
parent 7542ec0fbf
commit aaedf7a684
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 65 additions and 9 deletions

View File

@ -127,7 +127,8 @@ Then you can add the configuration:
"CaseSensitive": "boolean: should property names be case-sensitive? Defaults to false",
"DefaultPageSize": "int number: optional number to fallback to when no page argument is given. Set <=0 to disable paging if no pageSize is specified (default).",
"MaxPageSize": "int number: maximum allowed page size. Set <=0 to make infinite (default)",
"ThrowExceptions": "boolean: should Sieve throw exceptions instead of silently failing? Defaults to false"
"ThrowExceptions": "boolean: should Sieve throw exceptions instead of silently failing? Defaults to false",
"IgnoreNullsOnNotEqual": "boolean: ignore null values when filtering using is not equal operator? Default to true"
}
}
```

View File

@ -4,7 +4,8 @@
},
"Sieve": {
"CaseSensitive": false,
"DefaultPageSize": 10
"DefaultPageSize": 10,
"IgnoreNullsOnNotEqual": true
},
"Logging": {
"Debug": {

View File

@ -9,5 +9,7 @@
public int MaxPageSize { get; set; } = 0;
public bool ThrowExceptions { get; set; } = false;
public bool IgnoreNullsOnNotEqual { get; set; } = true;
}
}

View File

@ -217,11 +217,14 @@ namespace Sieve.Services
expression = Expression.Not(expression);
}
if (expression.NodeType != ExpressionType.NotEqual || Options.Value.IgnoreNullsOnNotEqual)
{
var filterValueNullCheck = GetFilterValueNullCheck(parameter, fullPropertyName, isFilterTermValueNull);
if (filterValueNullCheck != null)
{
expression = Expression.AndAlso(filterValueNullCheck, expression);
}
}
innerExpression = innerExpression == null
? expression
@ -254,8 +257,7 @@ namespace Sieve.Services
: result.Where(Expression.Lambda<Func<TEntity, bool>>(outerExpression, parameter));
}
private static Expression GetFilterValueNullCheck(Expression parameter, string fullPropertyName,
bool isFilterTermValueNull)
private static Expression GetFilterValueNullCheck(Expression parameter, string fullPropertyName, bool isFilterTermValueNull)
{
var (propertyValue, nullCheck) = GetPropertyValueAndNullCheckExpression(parameter, fullPropertyName);

View File

@ -15,16 +15,24 @@ namespace SieveUnitTests
{
private readonly ITestOutputHelper _testOutputHelper;
private readonly SieveProcessor _processor;
private readonly SieveProcessor _nullableProcessor;
private readonly IQueryable<Post> _posts;
private readonly IQueryable<Comment> _comments;
public General(ITestOutputHelper testOutputHelper)
{
var nullableAccessor = new SieveOptionsAccessor();
nullableAccessor.Value.IgnoreNullsOnNotEqual = false;
_testOutputHelper = testOutputHelper;
_processor = new ApplicationSieveProcessor(new SieveOptionsAccessor(),
new SieveCustomSortMethods(),
new SieveCustomFilterMethods());
_nullableProcessor = new ApplicationSieveProcessor(nullableAccessor,
new SieveCustomSortMethods(),
new SieveCustomFilterMethods());
_posts = new List<Post>
{
new Post
@ -180,8 +188,25 @@ namespace SieveUnitTests
};
var result = _processor.Apply(model, _posts);
var nullableResult = _nullableProcessor.Apply(model, _posts);
Assert.True(result.Count() == 2);
Assert.True(nullableResult.Count() == 2);
}
[Fact]
public void CanFilterNullableIntsWithNotEqual()
{
var model = new SieveModel()
{
Filters = "CategoryId!=1"
};
var result = _processor.Apply(model, _posts);
var nullableResult = _nullableProcessor.Apply(model, _posts);
Assert.True(result.Count() == 1);
Assert.True(nullableResult.Count() == 2);
}
[Theory]

View File

@ -16,16 +16,24 @@ namespace SieveUnitTests
{
private readonly ITestOutputHelper _testOutputHelper;
private readonly SieveProcessor _processor;
private readonly SieveProcessor _nullableProcessor;
private readonly IQueryable<IPost> _posts;
private readonly IQueryable<Comment> _comments;
public GeneralWithInterfaces(ITestOutputHelper testOutputHelper)
{
var nullableAccessor = new SieveOptionsAccessor();
nullableAccessor.Value.IgnoreNullsOnNotEqual = false;
_testOutputHelper = testOutputHelper;
_processor = new ApplicationSieveProcessor(new SieveOptionsAccessor(),
new SieveCustomSortMethods(),
new SieveCustomFilterMethods());
_nullableProcessor = new ApplicationSieveProcessor(nullableAccessor,
new SieveCustomSortMethods(),
new SieveCustomFilterMethods());
_posts = new List<IPost>
{
new Post
@ -181,8 +189,25 @@ namespace SieveUnitTests
};
var result = _processor.Apply(model, _posts);
var nullableResult = _nullableProcessor.Apply(model, _posts);
Assert.True(result.Count() == 2);
Assert.True(nullableResult.Count() == 2);
}
[Fact]
public void CanFilterNullableIntsWithNotEqual()
{
var model = new SieveModel()
{
Filters = "CategoryId!=1"
};
var result = _processor.Apply(model, _posts);
var nullableResult = _nullableProcessor.Apply(model, _posts);
Assert.True(result.Count() == 1);
Assert.True(nullableResult.Count() == 2);
}
[Fact]