diff --git a/src/OData.QueryBuilder/Expressions/Visitors/ODataOptionFilterExpressionVisitor.cs b/src/OData.QueryBuilder/Expressions/Visitors/ODataOptionFilterExpressionVisitor.cs index b3677ca2..9f8a7b18 100644 --- a/src/OData.QueryBuilder/Expressions/Visitors/ODataOptionFilterExpressionVisitor.cs +++ b/src/OData.QueryBuilder/Expressions/Visitors/ODataOptionFilterExpressionVisitor.cs @@ -277,10 +277,11 @@ protected override string VisitLambdaExpression(LambdaExpression topExpression, private bool HasParenthesis(ExpressionType expressionType) { - var hasParenthesis = _expressionType.HasValue && expressionType switch + + var hasParenthesis = expressionType switch { - ExpressionType.And => true, - ExpressionType.AndAlso => true, + ExpressionType.And => true && _expressionType.HasValue, + ExpressionType.AndAlso => true && _expressionType.HasValue, ExpressionType.Or => true, ExpressionType.OrElse => true, _ => false, diff --git a/test/OData.QueryBuilder.Test/ODataQueryCollectionTest.cs b/test/OData.QueryBuilder.Test/ODataQueryCollectionTest.cs index b28b7891..97948e02 100644 --- a/test/OData.QueryBuilder.Test/ODataQueryCollectionTest.cs +++ b/test/OData.QueryBuilder.Test/ODataQueryCollectionTest.cs @@ -1170,6 +1170,29 @@ public void ODataQueryBuilderList_Filter_support_parentheses_Success() $" and ODataKind/ODataCode/Code in ('123','512')"); } + [Fact(DisplayName = "Multiple filters wrap or in parenthesis => Success")] + public void ODataQueryBuilderList_Multiple_filters_wrap_or_in_parenthesis_Success() + { + var constStrIds = new[] { "123", "512" }; + var constValue = 3; + + var uri = _odataQueryBuilderDefault + .For(s => s.ODataType) + .ByList() + .Filter((s, f, o) => s.IdRule == constValue) + .Filter((s, f, o) => s.IsActive) + .Filter((s, f, o) => (f.Date(s.EndDate.Value) == default(DateTimeOffset?) || s.EndDate > DateTime.Today), useParenthesis: true) + .Filter((s, f, o) => (f.Date((DateTimeOffset)s.BeginDate) != default(DateTime?) || f.Date((DateTime)s.BeginDate) <= DateTime.Now), useParenthesis: true) + .Filter((s, f, o) => (o.In(s.ODataKind.ODataCode.Code, constStrIds))) + .ToUri(); + + uri.Should().Be($"http://mock/odata/ODataType?$filter=IdRule eq 3" + + $" and IsActive" + + $" and (date(EndDate) eq null or EndDate gt {DateTime.Today:s}Z)" + + $" and (date(BeginDate) ne null or date(BeginDate) le {DateTime.Now:s}Z)" + + $" and ODataKind/ODataCode/Code in ('123','512')"); + } + [Theory(DisplayName = "Count value => Success")] [InlineData(true)] [InlineData(false)]