Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

OData using $expand breaks cast operation due to wrapper

I'm experiencing the same problem as addressed here:

However, the answer is not sufficient for me. First of all I cannot for the life of me find HierarchyNodeExpressionVisitor in OData 5.0.0 (not RC1) (or anywhere for that matter, tried googling around).

Second even if I did find it returning IHttpActionResult is not good enough, I need to return a typed PageResult<MyViewModel>

The stated justificiation to return IHttpActionResult is "to handle the fact that the result might not be a IQueryable<MyEntity> anymore." once the $expand operator is used.

But this doesn't make sense to me because I thought the $expand operator is used to include a navigation property on entity just like a server side Include(e => e.RelatedProperty) would. At least in my case I'm only including a property already on the Entity so I don't have to worry about it "potentially being something else".

However when using $expand=Department I cannot Cast<>() to the entity type because it cannot cast SelectAllAndExpand<MyEntity> to a MyEntity.

How can I "unwrap" the expand back to the original entity so that I can do a projection?

public PageResult<DateSnippetWithDepartmentsViewModel> GetDatesWithDepartments(ODataQueryOptions<DateSnippet> options)
{
    IQueryable query = options.ApplyTo(_context.DateSnippets, new ODataQuerySettings());;

    //Exception when using $expand.. cannot cast SelectAllAndExpand<DateSnippet> to DateSnippet
    List<DateSnippet> dateSnippets = query.Cast<DateSnippet>().ToList();

    var dateSnippetsViewModels = (from d in dateSnippets
                                    select new DateSnippetWithDepartmentsViewModel
                                    {
                                        ...
                                    });

    var result = new PageResult<DateSnippetWithDepartmentsViewModel>(
            dateSnippetsViewModels as IEnumerable<DateSnippetWithDepartmentsViewModel>,
            Request.GetNextPageLink(),
            Request.GetInlineCount());

    return result;
}
like image 218
parliament Avatar asked Jan 07 '14 18:01

parliament


People also ask

What is the use of $expand in OData?

OData expand functionality can be used to query related data. For example, to get the Course data for each Enrollment entity, include ?$ expand=course at the end of the request path: This tutorial uses Postman to test the web API.

What is $value in OData?

The $value option is used to get individual properties of an Entity. There are two ways to get individual properties from an entity. We can get the response in either OData format or get the raw value of the property. We need to add method to the controller named GetProperty here property is a name of the property.

What is $select in OData?

The $select option specifies a subset of properties to include in the response body. For example, to get only the name and price of each product, use the following query: Console Copy. GET http://localhost/odata/Products?$select=Price,Name.


1 Answers

Try this. Hopefully should work, by the time we get to the Enumerator, the result should be a DateSnippet. What you were doing before was trying to cast in the Linq Expression tree. I suspect in the IQueryable Execute, that is resolved and converted as opposed to cast.

public PageResult<DateSnippetWithDepartmentsViewModel> GetDatesWithDepartments(ODataQueryOptions<DateSnippet> options)
{
    IQueryable query = options.ApplyTo(_context.DateSnippets, new ODataQuerySettings());;

    List<DateSnippet> dateSnippets = new List<DateSnippet>();
    foreach(DateSnippet item in query)
    {
        dateSnippets.Add(item);
    }

    var dateSnippetsViewModels = (from d in dateSnippets
                                    select new DateSnippetWithDepartmentsViewModel
                                    {
                                        ...
                                    });

    var result = new PageResult<DateSnippetWithDepartmentsViewModel>(
            dateSnippetsViewModels as IEnumerable<DateSnippetWithDepartmentsViewModel>,
            Request.GetNextPageLink(),
            Request.GetInlineCount());

    return result;
}
like image 93
Aron Avatar answered Oct 07 '22 12:10

Aron