QueryAsync throwing type cast exception (beta4)

I have upgraded the SDK from an earlier beta to beta4 and am now getting an exception on the following line of code that had been previously working:
IQueryResult<T> result = await _cluster.QueryAsync<T>(query, queryOptions);
where _cluster is an ICluster object
The exception:
System.InvalidCastException: Unable to cast object of type 'Couchbase.Query.StreamingQueryResult' to type 'Couchbase.Query.IQueryResult'.
I tried declaring the result as ‘Couchbase.Query.StreamingQueryResult’ instead, but end up getting the same exception. Looking at the ICluster implementation in github, it looks like it should return an IQueryResult which is what it was doing previously with an earlier beta. I don’t understand where the StreamingQueryResult is coming from, can you shed some light? Thank you.

@atkinsr -

Odd, I just ran through the integration tests query tests and all passed with green. Maybe @btburnett3 can shed some light? Is the error happening when you enumerate the results or just when the call happens?

-Jeff

@jmorris

The problem is the new automatic retry logic is doing queries using “dynamic” instead of “T”. The integration tests are missing it because they all query “dynamic”. I’m working on a fix now, and I will make the tests more robust as well.

@atkinsr

In the interrim, you can work around the problem by using _cluster.QueryAsync<dynamic>, though admittedly that’s a poor workaround.

https://issues.couchbase.com/browse/NCBC-2307

http://review.couchbase.org/#/c/121132/

Thank you for the very quick follow up on this. The workaround resolved the issue. I also see that you’ve already fixed this. I assume this will be in the next release of the SDK (or I could build from the master if I wanted the change now).

Resultant code using workaround…

IQueryResult<dynamic> result = null;
result = await _cluster.QueryAsync<dynamic>(query, queryOptions).ConfigureAwait(false);
await foreach (var row in result.ConfigureAwait(false))
{
   resultSet.Add(row.ToObject<T>());
}
result.Dispose();

@atkinsr

Glad the workaround worked, I’m sure @jmorris will be releasing the next version soon.

You might also try the new C# 8 using declarations feature to make the Dispose cleaner.

using var result = await _cluster.QueryAsync<dynamic>(query, queryOptions).ConfigureAwait(false);
await foreach (var row in result.ConfigureAwait(false))
{
   resultSet.Add(row.ToObject<T>());
}

Thank you. I like it! (C# “using”)