Description
In a specific scenario, where a [Contained] houses a EntitySet, an embedded navigational property two levels deep within said EntitySet will not be returned.
Assemblies affected
Microsoft.AspNet.OData lib 7.6.0
Reproduce steps
The following entities are defined:
public class Customer
{
[Key]
public int ID { get; set; }
[Contained]
public ICollection<CustomerReferral> CustomerReferrals { get; set; }
[Contained]
public ICollection<CustomerPhone> Phones { get; set; }
}
public class CustomerReferral
{
[Key]
public int ID { get; set; }
public int CustomerID { get; set; }
public int ReferredCustomerID { get; set; }
[Required]
[ForeignKey(nameof(CustomerID))]
public Customer Customer { get; set; }
[Required]
[ForeignKey(nameof(ReferredCustomerID))]
public Customer ReferredCustomer { get; set; }
}
public class CustomerPhone
{
[Key]
public int ID { get; set; }
[Editable(false)]
public int CustomerID { get; set; }
[Contained]
public CustomerPhoneNumberFormatted Formatted { get; set; }
}
public class CustomerPhoneNumberFormatted
{
[Key]
public int CustomerPhoneNumberID { get; set; }
public string FormattedNumber { get; set; }
}
The DbContext model builder has the following:
modelBuilder.Entity<CustomerPhone>().HasOptional(a => a.Formatted).WithRequired();
modelBuilder.Entity<Customer>()
.HasMany(c => c.CustomerReferrals)
.WithRequired(c => c.Customer)
.HasForeignKey(c => c.CustomerID);
The OData model builder is as follows:
ODataModelBuilder builder = new ODataConventionModelBuilder();
builder.EntitySet<Customer>("Customers");
A defined route is established for CustomerReferrals from a Customer, and the following query is applied:
salesinventory/Customers(486)/CustomerReferrals?$expand=ReferredCustomer($expand=Phones($expand=Formatted))
Expected result
The Formatted entity is returned in the results.
Actual result
The Formatted entity is not returned. Everything is returned except the Formatted entity.
Additional detail
The breakdown seems to happen during the serialization of the OData resource. The actual underlining SQL call and the entities returned to the ODataResourceSerializer have the Formatted class, but it is dropped. This seems to be as the NavigationSource is null on the given ResourceContext for CustomerPhone.