Rob Lyndon
Rob Lyndon

Reputation: 12671

IMobileServiceTableQuery does not send correct parameters to server

I have this function, that sends queries down to my Azure Mobile servce:

let pullTable<'a when 'a :> EntityDto> (logger: ILog) (table: Sync.IMobileServiceSyncTable<'a>) (tableQuery: IMobileServiceTableQuery<'a>) =
    async {
        match CrossConnectivity.Current.IsConnected with
        | false -> ()
        | true ->
            try 
                do! table.PullAsync (Unchecked.defaultof<string>, tableQuery) |> Async.AwaitTask
            with 
                | ex -> logger.Warning Tag (sprintf "Transient error: Connection failure") (Some ex)
    }

It is called from this method:

member this.GetVenuesAsync managerId =
    async {
        do! initialiseSyncContext mobileServiceClient
        let table = mobileServiceClient.GetSyncTable<VenueDto>()
        do! pullTable logger table (table.Where(fun v -> v.ManagerId = managerId))
        let! results = table.ToEnumerableAsync() |> Async.AwaitTask
        return results |> Array.ofSeq
    }

Unfortunately, the Where clause in this method is completely ineffectual: it brings back all of the venues.

Stopping the server at the endpoint, no filter has been added to the Odata query generated by table.PullAsync. This looks like a bug to me.

  1. Have I made a mistake somewhere?
  2. If this is a bug, i. Are there any workarounds? ii. Is there a place to report it?

EDIT 1: I have also tried this variation, with no success:

member this.GetVenuesAsync managerId =
    async {
        do! initialiseSyncContext mobileServiceClient
        let table = mobileServiceClient.GetSyncTable<VenueDto>()
        do! pullTable logger table (table.CreateQuery())
        let! results = table.Where(fun v -> v.ManagerId = managerId).ToEnumerableAsync() |> Async.AwaitTask
        return results |> Array.ofSeq
    }

EDIT 2: Bruce Chen's answer was a partial solution, but it has highlighted another problem, which I believe is F# specific. With

do! pullTable logger table (table.CreateQuery().Where(fun v -> v.ManagerId = managerId))

The endpoint does indeed pick up the filter, but the filter is unfortunately in the wrong format. At my TableController's endpoint

[EnableQuery] public IHttpActionResult Get() => Ok(Query());

the RequestUrl has a query string containing $filter=(managerId%20eq%202L). This L suffix is a problem: managerId is defined as an int, not a long. But the odata endpoint interprets it as a long. I don't know if there is an easy way to fix this.

Upvotes: 1

Views: 145

Answers (1)

Bruce Chen
Bruce Chen

Reputation: 18465

Per my understanding, you could try to change your code as follows for pulling records from the remote Venue table with the specific ManagerId via the PullAsync method.

do! pullTable logger table (table.CreateQuery())

//To

do! pullTable logger table (table.CreateQuery().Where(fun v -> v.ManagerId = managerId))

Here is the tutorial for pulling records with filters wrote in C#, you could refer to it and check with your code.

Upvotes: 1

Related Questions