0
votes

I have a WebAPI built over a Domain specific data model which uses a proprietary data store.

The data store has a SDK which allows for typical retrieval/filtering operations that one might want to perform via OData such as 'and', 'or', 'eq', 'ne' and functions such as 'substring' etc.

My endpoint(s) accept ODataQueryOptions<T> where T = DTO.

I can get to the representation of $filter via the options.Filter which returns a FilterQueryOption

which in turn contains a FilterClause property representing an AST for the $filter.

I am looking for guidance and examples on:

  1. Is there a best/prescribed way of traversing this AST so that I can built a corresponding domain-specific query to issue calls to the underlying data store via it's SDK.

  2. If there is a supported way to do the above, will the navigation navigate the tree in a manner so as to preserve OData operator precedence

NOTE:

  1. I am not using Web API 2.0

  2. Implementing IQueryable is not an option given the lack of proper guidance and the complexity/effort involved in doing this.

1

1 Answers

0
votes

I dont know about a 'best' way but here's a general approach I would take for traversing/parsing a complex expression (partial pseudo code). This approach preserves the operator precedence.

string Expression(inValue)
{
    //expression can be any of Literal, OR, AND, Equality, Greater Than etc...
    if(inValue is boolean or)
        return BooleanOR(inValue);
    else if(inValue is boolean and)
        return BooleanAND(inValue);
    else if(inValue is equality comparison)
        return Equality(inValue);
    //...etc etc
    else
        return inValue.LiteralValue;
}

string BooleanOR(inValue)
{
    return "(" + Expression(inValue.Operand1) + " OR " + Expression(inValue.Operand2) + ")";
}

string BooleanAND(inValue)
{
    return "(" + Expression(inValue.Operand1) + " AND " + Expression(inValue.Operand2) + ")";
}

string Equality(inValue)
{
    return "(" + Expression(inValue.Operand1) + " = " + Expression(inValue.Operand2) + ")";
}