Search code examples
c#asp.net-web-apiodata

Using Complex types in OData queries


I'm trying to sort my data by a complex type Address that's is on my main entity Customer.

public partial class Customer
{
    public Customer()
    {
        this.Address = new Address();
    }

    public string Name { get; set; }
    public Address Address { get; set; }
}

public partial class Address
{
    public string Address1 { get; set; }
    public string Address2 { get; set; }
    public string Town { get; set; }
    public string County { get; set; }
    public string PostCode { get; set; }
}

I've queried the data, and I can sort it by name using $sort=Name, but when I do $sort=Address.PostCode I get:

"The child type 'Address.PostCode' in a cast was not an entity type. Casts can only be performed on entity types.","type":"Microsoft.Data.OData.ODataException","stacktrace":" at Microsoft.Data.OData.Query.DottedIdentifierBinder.BindDottedIdentifier(DottedIdentifierToken dottedIdentifierToken, BindingState state)\r\n at Microsoft.Data.OData.Query.MetadataBinder.BindCast(DottedIdentifierToken dottedIdentifierToken)\r\n at Microsoft.Data.OData.Query.MetadataBinder.Bind(QueryToken token)\r\n at Microsoft.Data.OData.Query.OrderByBinder.ProcessSingleOrderBy(BindingState state, OrderByClause thenBy, OrderByToken orderByToken)\r\n at Microsoft.Data.OData.Query.OrderByBinder.BindOrderBy(BindingState state, IEnumerable1 orderByTokens)\r\n at Microsoft.Data.OData.Query.ODataUriParser.ParseOrderByImplementation(String orderBy, IEdmType elementType, IEdmEntitySet entitySet)\r\n at System.Web.Http.OData.Query.OrderByQueryOption.get_OrderByClause()\r\n at System.Web.Http.OData.Query.OrderByQueryOption.get_OrderByNodes()\r\n at System.Web.Http.OData.Query.ODataQueryOptions.EnsureStableSortOrderBy(OrderByQueryOption orderBy, ODataQueryContext context)\r\n at System.Web.Http.OData.Query.ODataQueryOptions.ApplyTo(IQueryable query, ODataQuerySettings querySettings)\r\n at System.Web.Http.QueryableAttribute.ApplyQuery(IQueryable queryable, ODataQueryOptions queryOptions)\r\n at System.Web.Http.QueryableAttribute.ExecuteQuery(Object response, HttpRequestMessage request, HttpActionDescriptor actionDescriptor)\r\n at System.Web.Http.QueryableAttribute.OnActionExecuted(HttpActionExecutedContext actionExecutedContext)"

When I do $sort=Address/PostCode I get:

"Only ordering by properties at the root level is supported for non-primitive collections. Nested properties and expressions are not supported.","type":"Microsoft.Data.OData.ODataException","stacktrace":" at System.Web.Http.OData.Query.OrderByNode.CreateCollection(OrderByClause orderByClause)\r\n at System.Web.Http.OData.Query.OrderByQueryOption.get_OrderByNodes()\r\n at System.Web.Http.OData.Query.ODataQueryOptions.EnsureStableSortOrderBy(OrderByQueryOption orderBy, ODataQueryContext context)\r\n at System.Web.Http.OData.Query.ODataQueryOptions.ApplyTo(IQueryable query, ODataQuerySettings querySettings)\r\n at System.Web.Http.QueryableAttribute.ApplyQuery(IQueryable queryable, ODataQueryOptions queryOptions)\r\n at System.Web.Http.QueryableAttribute.ExecuteQuery(Object response, HttpRequestMessage request, HttpActionDescriptor actionDescriptor)\r\n at System.Web.Http.QueryableAttribute.OnActionExecuted(HttpActionExecutedContext actionExecutedContext)"

So how do I sort it?

I'm using Entity Framework v6 and System.Web.Http.OData v5.

Thanks


Solution

  • The syntax for $orderby on nested properties is the later i.e you should do $orderby=Address/PostCode.

    And, we didn't have support for $orderby on nested properties in V2 RTM (the current bits). However, we recently fixed that and this feature is available in our nightly builds and would be available on nuget in our next release.

    To access our nightly builds, you could follow this link for details.