diff --git a/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs b/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs index 3858ccc2..9362dc94 100644 --- a/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/ReflectionExtensions.cs @@ -7,22 +7,12 @@ namespace OData.QueryBuilder.Extensions { internal static class ReflectionExtensions { - public static object GetValue(this MemberInfo memberInfo, object obj = default) + public static object GetValue(this MemberInfo memberInfo, object obj = default) => memberInfo switch { - try - { - return memberInfo switch - { - FieldInfo fieldInfo => fieldInfo.GetValue(obj), - PropertyInfo propertyInfo => propertyInfo.GetValue(obj, default), - _ => default, - }; - } - catch (Exception) - { - return default; - } - } + FieldInfo fieldInfo => fieldInfo.GetValue(obj), + PropertyInfo propertyInfo => propertyInfo.GetValue(obj, default), + _ => default, + }; public static bool IsNullableType(this Type type) => Nullable.GetUnderlyingType(type) != default; @@ -32,7 +22,7 @@ public static string ConvertToString(object @object) switch (@object) { case null: - return default; + return "null"; case string @string: return $"'{@string}'"; case bool @bool: diff --git a/src/OData.QueryBuilder/Extensions/StringExtensions.cs b/src/OData.QueryBuilder/Extensions/StringExtensions.cs index eaa0ace2..c4053c7c 100644 --- a/src/OData.QueryBuilder/Extensions/StringExtensions.cs +++ b/src/OData.QueryBuilder/Extensions/StringExtensions.cs @@ -3,6 +3,6 @@ internal static class StringExtensions { public static bool IsNullOrQuotes(this string value) => - string.IsNullOrEmpty(value) || value == "''"; + string.IsNullOrEmpty(value) || value == "null" || value == "''"; } } diff --git a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs index dee2c2b1..76495853 100644 --- a/src/OData.QueryBuilder/Visitors/VisitorExpression.cs +++ b/src/OData.QueryBuilder/Visitors/VisitorExpression.cs @@ -51,8 +51,7 @@ protected virtual string VisitMemberExpression(MemberExpression memberExpression CreateResourcePath(memberExpression) : ReflectionExtensions.ConvertToString(GetValueOfMemberExpression(memberExpression)); protected virtual string VisitConstantExpression(ConstantExpression constantExpression) => - constantExpression.Value == default ? - "null" : ReflectionExtensions.ConvertToString(constantExpression.Value); + ReflectionExtensions.ConvertToString(constantExpression.Value); protected virtual string VisitMethodCallExpression(MethodCallExpression methodCallExpression) { diff --git a/test/OData.QueryBuilder.Test/ODataQueryOptionListTest.cs b/test/OData.QueryBuilder.Test/ODataQueryOptionListTest.cs index 9ccd40bf..d2dfce7a 100644 --- a/test/OData.QueryBuilder.Test/ODataQueryOptionListTest.cs +++ b/test/OData.QueryBuilder.Test/ODataQueryOptionListTest.cs @@ -246,6 +246,20 @@ public void ODataQueryBuilderList_Expand_Filter_Select_OrderBy_OrderByDescending uri.OriginalString.Should().Be($"http://mock/odata/ODataType?$expand=ODataKind&$filter=IdType lt 2 and 3 le ODataKind/ODataCode/IdCode or IdType eq 5 and IdRule ne null and IdRule eq null&$select=ODataKind,Sum&$orderby=IdType asc&$skip=1&$top=1&$count=true"); } + [Fact(DisplayName = "Filter nullable bool eq null => Success")] + public void ODataQueryBuilderList_filter_nullable_bool_eq_null_success() + { + var constValue = default(bool?); + + var uri = _odataQueryBuilderDefault + .For(s => s.ODataType) + .ByList() + .Filter(s => s.IsOpen == constValue) + .ToUri(); + + uri.OriginalString.Should().Be("http://mock/odata/ODataType?$filter=IsOpen eq null"); + } + [Fact(DisplayName = "Function Date => Success")] public void ODataQueryBuilderList_Function_Date_Success() {