diff --git a/test/Microsoft.AspNetCore.OData.Tests/Query/Expressions/SelectExpandBinderTest.cs b/test/Microsoft.AspNetCore.OData.Tests/Query/Expressions/SelectExpandBinderTest.cs index bdeeef076..353c86390 100644 --- a/test/Microsoft.AspNetCore.OData.Tests/Query/Expressions/SelectExpandBinderTest.cs +++ b/test/Microsoft.AspNetCore.OData.Tests/Query/Expressions/SelectExpandBinderTest.cs @@ -10,6 +10,7 @@ using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.DataAnnotations; +using System.ComponentModel.DataAnnotations.Schema; using System.Linq; using System.Linq.Expressions; using System.Reflection; @@ -356,6 +357,52 @@ public void Bind_UsingEFQueryProvider_LowerCamelCasedModel_GeneratedExpression__ Assert.Null(innerInnerCustomer.Instance.Orders); } + [Fact] + public void Bind_SelectAndExpand_WithNullProperties_DoesNotThrowException() + { + // Arrange + IQueryable users; + string expand = "FileRefNavigation"; + + User user = new User + { + UserId = 1, + Name = "Alex", + Age = 35, + DataFileRef = null, + FileRefNavigation = null + }; + + users = new[] { user }.AsQueryable(); + ODataQueryContext context = new ODataQueryContext(_model, typeof(User)) { RequestContainer = new MockServiceProvider() }; + + SelectExpandQueryOption selectExpand = new SelectExpandQueryOption(select: null, expand: expand, context: context); + + QueryBinderContext queryBinderContext = new QueryBinderContext(_model, _settings, selectExpand.Context.ElementClrType) + { + NavigationSource = context.NavigationSource + }; + + queryBinderContext.QueryProvider = HandleNullPropagationOptionHelper.EntityFrameworkQueryProviderNamespace; + + // Act + SelectExpandBinder binder = new SelectExpandBinder(); + IQueryable queryable = binder.ApplyBind(users, selectExpand.SelectExpandClause, queryBinderContext); + + // Assert + Assert.NotNull(queryable); + + IEnumerator enumerator = queryable.GetEnumerator(); + Assert.True(enumerator.MoveNext()); + var usr = Assert.IsAssignableFrom>(enumerator.Current); + Assert.False(enumerator.MoveNext()); + Assert.NotNull(usr.Instance); + Assert.Equal("Microsoft.AspNetCore.OData.Tests.Query.Expressions.User", usr.Instance.GetType().ToString()); + IEnumerable> fileRefsNavigations = usr.Container + .ToDictionary(PropertyMapper)["FileRefNavigation"] as IEnumerable>; + Assert.Null(fileRefsNavigations); + } + [Fact] public void Bind_GeneratedExpression_CheckNullObjectWithinChainProjectionByKey() { @@ -2095,6 +2142,7 @@ public static IEdmModel GetEdmModel() builder.EntitySet("Orders"); builder.EntitySet("Cities"); builder.EntitySet("Products"); + builder.EntitySet("Users"); customer.Collection.Function("IsUpgraded").Returns().Namespace="NS"; customer.Collection.Action("UpgradeAll").Namespace = "NS"; @@ -2305,4 +2353,27 @@ public enum QueryColor Blue } + + public class User + { + [Key] + public int UserId { get; set; } + [Required] + public string Name { get; set; } + [Required] + public int Age { get; set; } + + //Navigations + [ForeignKey("FileRefNavigation")] + public int? DataFileRef { get; set; } + public DataFile? FileRefNavigation { get; set; } + } + + public class DataFile + { + [Key] + public int FileId { get; set; } + [Required] + public string FileName { get; set; } + } }