oreubens
oreubens

Reputation: 339

WebApi 2.0 OData, obtain list of SQL tables used in the query

I have a fairly standard WebApi 2.0 OData 4.0 webservice using EF5, and code first approach. This service works and I can query entities and related entities through foreign keys.

The service is read-only and the controllers only have a Get and Get-by-key implemented.

public class MyTableController : MyDbController
{
    [EnableQuery]
    public IQueryable<MyTable> Get()
    {
        return db.MyTable;
    }

    [EnableQuery]
    public SingleResult<MyTable> Get([FromODataUri] int key)
    {
        IQueryable<MyTable> result = db.MyTable.Where(p => p.pk == key);
        return SingleResult.Create(result);
    }
}

In both Get() implementations, I would like to have access to the list of tables that are being used in the OData and resulting SQL query. MyTable is obviously one of them, but how do I obtain the others (among others, the ones used in (nested) $expand)? I can try to parse the URL myself, but that's doesn't seem like a very good way to go about it.

Upvotes: 0

Views: 534

Answers (1)

Fan Ouyang
Fan Ouyang

Reputation: 2142

  1. Create a class CustomizeAttribute inherit from EnableQueryAttribute
  2. Override this method : public virtual IQueryable ApplyQuery
  3. then you get the queryOptions in this method, you can go to the SelectExpandQueryOption and find the ExpandItem, then you get all the table.

    public override IQueryable ApplyQuery(IQueryable queryable, ODataQueryOptions queryOptions)
    {
        if (queryOptions.SelectExpand != null)
        {
            foreach (var selectItem in queryOptions.SelectExpand.SelectExpandClause.SelectedItems)
            {
                var expandedItem = selectItem as ExpandedNavigationSelectItem;
                if (expandedItem != null)
                {
                    // get the entitySetName, tableName
                    string entitySetName = expandedItem.NavigationSource.Name;
                   // can go recursive with expandItem.SelectExpandClause in case we have $epxand=A($expand=B)
                }
            }
        }
        return base.ApplyQuery(queryable, queryOptions);
    }
    
  4. Use this attribute on Controller method

    [CustomizeAttribute]
    public IQueryable<MyTable> Get()
    {
        return db.MyTable;
    }
    

Upvotes: 1

Related Questions