Marty78
Marty78

Reputation: 97

ASP.NET C# OData Service + Navigation Property + $expand = null. What am I missing?

I will try to explain my problem as thoroughly as possible with a simplified example. Please note that I am NOT using Entity Framework.

I have this model:

public class Person
{
    [Key]
    public Guid Id { get; set; }
    public string GivenName { get; set; }
    public string FamilyName { get; set; }
    public List<Employment> Employments { get; set; } 
}

public class Employment
{
    public string Role { get; set; }
    public Guid? ManagerId { get; set; }
    public virtual Person Manager { get; set; }
}

I create an in-memory data source:

public class MyDataSource
{
    private static MyDataSource instance = null;
    public static MyDataSource Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new MyDataSource();
            }
            return instance;
        }
    }
    public List<Person> Persons  { get; set; }
    private MyDataSource()
    {
        this.Persons = new List<Person>();
        this.Persons.AddRange(new List<Person>
        {
            new Person()
            {
                Id = Guid.Parse("00000000-0000-0000-0000-000000000001"), //Just for simplicity
                GivenName = "John",
                FamilyName = "Doe",
                Employments = new List<Employment>()
                {
                    new Employment()
                    {
                        Role = "Boss"
                    }
                }
            },
            new Person()
            {
                Id = Guid.Parse("00000000-0000-0000-0000-000000000002"), //Just for simplicity
                GivenName = "Clark",
                FamilyName = "Kent",
                Employments = new List<Employment>()
                {
                    new Employment()
                    {
                        Role = "Worker",
                        ManagerId = Guid.Parse("00000000-0000-0000-0000-000000000001"), //Just for simplicity
                    }
                }
            }
        });
    }
}

I have this controller:

[EnableQuery]
public class PersonsController : ODataController
{
    public IHttpActionResult Get()
    {
        return Ok(MyDataSource.Instance.Persons)
    }
}

I configure the EndPoint:

public static class WebApiConfig
{
    public static void Register(HttpConfiguration config)
    {
        config.MapODataServiceRoute("ODataRoute", "odata", CreateEdmModel());
        config.Select().Expand().Filter().OrderBy().MaxTop(null).Count()
    }

    public static IEdmModel CreateEdmModel()
    {
        var builder = new ODataConventionModelBuilder();
        var persons = builder.EntitySet<Person>("Persons");
        builder.ComplexType<Employment>().HasOptional(e => e.Manager, (e, p) => e.ManagerId == p.Id);
        return builder.GetEdmModel();
    }
}

Checking the $metadata I see this:

<NavigationProperty Name="Manager" Type = "MyNamespace.Person">
    <ReferentialConstraint Property="ManagerId" ReferenceProperty="Id" />
</NavigationProperty

Everything looks fine from what I can tell but:

https://example.com/odata/persons?$expand=Employments/Manager

receives everything fine but:

Manager is null for both persons. I was expecting to see John Doe on Clark Kents employment.

What am I missing?

Upvotes: 0

Views: 316

Answers (1)

Marty78
Marty78

Reputation: 97

I have solved it myself.

I realised that it doesn't work like I thought and that I have to add a reference to the manager directly in MyDataSource. After that it works to $expand the manager.

Upvotes: 1

Related Questions