score:13

Accepted answer

you can call tostring() on the documentdb query to get the sql translation of the linq expression that's sent over the wire.

string sql = client.createdocumentquery<mytype>(collectionuri).where(t => t.name = "x").tostring();
// sql is somthing like select * from c where c["name"] = "x"

score:0

the accepted answer is kind of weird : it means that you have to log each and every piece of linq code you made.

(using aspnetcore di). knowing that the microsoft.azure.cosmos.cosmosclient contains an httpclient, the first thing we can do is search if we can pass our own httpclient.

and we can. for example, via cosmosclientbuilder and using the injected ihttpclientfactory :

.withhttpclientfactory(() => httpclientfactory.createclient("client"))

if your log filters are well configured, you'll see the request / response in the console.

now, we could either add a delegatinghandler to our httpclient this way in configureservices or builder.services in .net 6 :

services.addtransient<nosqlloggingdelegatinghandler>();
services.addhttpclient("client")
    .addhttpmessagehandler<nosqlloggingdelegatinghandler>();

or find out if cosmosclient has the option to add our own, and of course it does (example via cosmosclientbuilder).

.addcustomhandlers(
    new nosqlloggingdelegatinghandler(loggerfactory.createlogger<nosqlloggingdelegatinghandler>()))

with this, we can intercept the request and response sent :

public override async task<responsemessage> sendasync(requestmessage request, cancellationtoken cancellationtoken)
{
    _logger.loginformation("requesting {uri}.\n{query}",
            request.requesturi, await getqueryasync(request.content));

    responsemessage response = await base.sendasync(request, cancellationtoken);

    _logger.loginformation("requested {uri} - {status}",
    response.requestmessage.requesturi, response.statuscode);

    return response;
}

and getqueryasync reads the request's body stream using system.text.json :

private static async valuetask<string?> getqueryasync(stream content)
{
    string? stringcontents;

    // create a streamreader with leaveopen = true so it doesn't close the stream when disposed
    using (streamreader sr = new streamreader(content, encoding.utf8, true, 1024, true))
    {
        stringcontents = await sr.readtoendasync();
    }

    content.position = 0;

    if (string.isnullorempty(stringcontents))
    {
        return null;
    }

    try
    {
        using jsondocument parsedjobject = jsondocument.parse(stringcontents);

        return parsedjobject.rootelement.getproperty("query").getstring();
    }
    catch (keynotfoundexception)
    {
        return stringcontents;
    }
    // not a json.
    catch (jsonexception)
    {
        return stringcontents;
    }
}

and there you have it. i've tried to shortened the code, for example, i didn't add a condition to check if the logging level is enabled or not, to avoid doing useless work.

score:5

you could just use fiddler and view the json of the request after it is sent.

view an example here:

cosmosdb\documentdb generated sql query


Related Query

More Query from same tag