diff --git a/Directory.Build.props b/Directory.Build.props index 63430d32..725ab47c 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -4,7 +4,7 @@ - 1.0.13 + 1.0.14 diff --git a/GitHubReleaseNotes.txt b/GitHubReleaseNotes.txt index 1a08b3d5..7c892631 100644 --- a/GitHubReleaseNotes.txt +++ b/GitHubReleaseNotes.txt @@ -1,3 +1,3 @@ https://github.com/StefH/GitHubReleaseNotes -GitHubReleaseNotes.exe . --output CHANGELOG.md --skip-empty-releases --language en --version 1.0.13.0 +GitHubReleaseNotes.exe . --output CHANGELOG.md --skip-empty-releases --language en --version 1.0.14.0 diff --git a/src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs b/src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs index 0f9aac11..1a1b3424 100644 --- a/src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs +++ b/src/System.Linq.Dynamic.Core/Parser/ExpressionParser.cs @@ -1177,7 +1177,7 @@ Expression GenerateConditional(Expression test, Expression expr1, Expression exp // - convert expr2 to nullable if (Constants.IsNull(expr1) && expr2.Type.GetTypeInfo().IsValueType) { - Type nullableType = typeof(Nullable<>).MakeGenericType(expr2.Type); + Type nullableType = TypeHelper.ToNullableType(expr2.Type); expr1 = Expression.Constant(null, nullableType); expr2 = Expression.Convert(expr2, nullableType); } @@ -1187,7 +1187,7 @@ Expression GenerateConditional(Expression test, Expression expr1, Expression exp // - convert expr1 to nullable if (Constants.IsNull(expr2) && expr1.Type.GetTypeInfo().IsValueType) { - Type nullableType = typeof(Nullable<>).MakeGenericType(expr1.Type); + Type nullableType = TypeHelper.ToNullableType(expr1.Type); expr2 = Expression.Constant(null, nullableType); expr1 = Expression.Convert(expr1, nullableType); } diff --git a/src/System.Linq.Dynamic.Core/Parser/TypeHelper.cs b/src/System.Linq.Dynamic.Core/Parser/TypeHelper.cs index 2c7e8e46..a234fe5a 100644 --- a/src/System.Linq.Dynamic.Core/Parser/TypeHelper.cs +++ b/src/System.Linq.Dynamic.Core/Parser/TypeHelper.cs @@ -260,6 +260,13 @@ public static bool IsNullableType(Type type) return type.GetTypeInfo().IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>); } + public static Type ToNullableType(Type type) + { + Check.NotNull(type, nameof(type)); + + return IsNullableType(type) ? type : typeof(Nullable<>).MakeGenericType(type); + } + public static bool IsSignedIntegralType(Type type) { return GetNumericTypeKind(type) == 2; diff --git a/test/System.Linq.Dynamic.Core.Tests/ExpressionTests.cs b/test/System.Linq.Dynamic.Core.Tests/ExpressionTests.cs index d4104539..d753d13b 100644 --- a/test/System.Linq.Dynamic.Core.Tests/ExpressionTests.cs +++ b/test/System.Linq.Dynamic.Core.Tests/ExpressionTests.cs @@ -1290,7 +1290,39 @@ public void ExpressionTests_NullCoalescing() } [Fact] - public void ExpressionTests_NullPropagating_Null() + public void ExpressionTests_NullPropagating_DateTime_Value() + { + // Arrange + var q = new[] { + new { id = 1, date1 = (DateTime?) DateTime.Now, date2 = DateTime.Now.AddDays(-1)} + }.AsQueryable(); + + // Act + var result = q.OrderBy(x => x.date2).Select(x => x.id).ToArray(); + var resultDynamic = q.OrderBy("np(date2)").Select("id").ToDynamicArray(); + + // Assert + Check.That(resultDynamic).ContainsExactly(result); + } + + [Fact] + public void ExpressionTests_NullPropagating_NullableDateTime() + { + // Arrange + var q = new[] { + new { id = 1, date1 = (DateTime?) DateTime.Now, date2 = DateTime.Now.AddDays(-1)} + }.AsQueryable(); + + // Act + var result = q.OrderBy(x => x.date1).Select(x => x.id).ToArray(); + var resultDynamic = q.OrderBy("np(date1)").Select("id").ToDynamicArray(); + + // Assert + Check.That(resultDynamic).ContainsExactly(result); + } + + [Fact] + public void ExpressionTests_NullPropagating_Integer_Null() { // Arrange var testModels = User.GenerateSampleModels(2, true).ToList(); @@ -1306,7 +1338,7 @@ public void ExpressionTests_NullPropagating_Null() } [Fact] - public void ExpressionTests_NullPropagating_Value() + public void ExpressionTests_NullPropagating_Integer_Value() { // Arrange var testModels = User.GenerateSampleModels(2, true).ToList();