From 800166239db589dfb606bb120f793f4aa75eef31 Mon Sep 17 00:00:00 2001 From: Kennedy Kangethe Date: Wed, 21 Oct 2020 14:19:02 -0700 Subject: [PATCH] Issue #2255,Create the correct expression when casting entity/complex type to derived type. PR #2299 --- .../Query/Expressions/FilterBinder.cs | 15 +++++++++++++-- .../Query/Expressions/FilterBinderTests.cs | 2 +- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.AspNet.OData.Shared/Query/Expressions/FilterBinder.cs b/src/Microsoft.AspNet.OData.Shared/Query/Expressions/FilterBinder.cs index 1bb888b91e..7d8d873713 100644 --- a/src/Microsoft.AspNet.OData.Shared/Query/Expressions/FilterBinder.cs +++ b/src/Microsoft.AspNet.OData.Shared/Query/Expressions/FilterBinder.cs @@ -337,8 +337,19 @@ private Expression BindSingleResourceCastFunctionCall(SingleResourceFunctionCall else if (arguments[0].Type.IsAssignableFrom(targetClrType)) { // To support to cast Entity/Complex type to the sub type now. - Expression source = BindCastSourceNode(node.Source); - + Expression source; + if(node.Source != null) + { + source = BindCastSourceNode(node.Source); + } + else + { + // if the cast is on the root i.e $it (~/Products?$filter=NS.PopularProducts/.....), + // node.Source would be null. Calling BindCastSourceNode will always return '$it'. + // In scenarios where we are casting a navigation property to return an expression that queries against the parent property, + // we need to have a memberAccess expression e.g '$it.Category'. We can get this from arguments[0]. + source = arguments[0]; + } return Expression.TypeAs(source, targetClrType); } else diff --git a/test/UnitTest/Microsoft.AspNet.OData.Test.Shared/Query/Expressions/FilterBinderTests.cs b/test/UnitTest/Microsoft.AspNet.OData.Test.Shared/Query/Expressions/FilterBinderTests.cs index 77632043a6..fff55f9b46 100644 --- a/test/UnitTest/Microsoft.AspNet.OData.Test.Shared/Query/Expressions/FilterBinderTests.cs +++ b/test/UnitTest/Microsoft.AspNet.OData.Test.Shared/Query/Expressions/FilterBinderTests.cs @@ -2316,7 +2316,7 @@ public void CastToUnquotedEntityType_ThrowsODataException(string filter, string [Theory] [InlineData("cast('Microsoft.AspNet.OData.Test.Query.Expressions.DerivedProduct')/DerivedProductName eq null", "$it => (($it As DerivedProduct).DerivedProductName == null)","$it => (IIF((($it As DerivedProduct) == null), null, ($it As DerivedProduct).DerivedProductName) == null)")] - [InlineData("cast(Category,'Microsoft.AspNet.OData.Test.Query.Expressions.DerivedCategory')/DerivedCategoryName eq null", "$it => (($it As DerivedCategory).DerivedCategoryName == null)", "$it => (IIF((($it As DerivedCategory) == null), null, ($it As DerivedCategory).DerivedCategoryName) == null)")] + [InlineData("cast(Category,'Microsoft.AspNet.OData.Test.Query.Expressions.DerivedCategory')/DerivedCategoryName eq null", "$it => (($it.Category As DerivedCategory).DerivedCategoryName == null)", "$it => (IIF((($it.Category As DerivedCategory) == null), null, ($it.Category As DerivedCategory).DerivedCategoryName) == null)")] public void CastToQuotedEntityOrComplexType_DerivedProductName(string filter, string expectedExpression, string expectedExpressionWithNullCheck) { // Arrange, Act & Assert