Skip to content

02. Features

Akos Nagy edited this page Feb 3, 2019 · 2 revisions

Features

Static driver

A static driver uses a prebuilt dll that you have to load to discover the data source and run the queries. To help you get started, I created a class library called ContextLibrary. You can use the base classes and methods in this class library to build your static driver data context, load it into LinqPad and get querying. I included some samples on how to use it in the StaticDriverDataContext project.

Dynamic driver

I implemented a dynamic driver too, but since there's no schema or structure wahtsorever to be discovered automatically by the driver, some sacrificies were necessary. The most important one being the fact the everything runs on the client side. If you create a query against a collection, the contents of the collection are downloaded and then you are essentially making Linq-to-objects queries.

The problem comes from the fact that in order to support a schemaless structure, dynamic have to be used. But Linq and dynamic don't really mix well (expression trees cannot contain dynamic references) so I had to get creative and this is what I came up with. Go ahead and check out the source code; if you have a better idea, suggestions and PRs are welcome.

Querying collections with Linq

If you load up the driver and connect to a data source, the driver automatically discovers the collections that are available and you can run queries against them:

If you use the dynamic driver, as mentioned before, you are basically running Linq-to-objects queries against the downloaded contents of the collection. If you use the static driver, then the queries you create are executed on the server-side.

As a bonus, if you right-click on a collection, you have all sorts of shortcuts to execute queries:

If you use the static driver, you also get SQL translation in the SQL window:

Setting FeedOptions

You can set the feedoptions for the queries per collection to determine how the underlying DocumentClient executes the queries:

The currently supported feedoptions:

DisableRUPerMinuteUsage Gets or sets the DisableRUPerMinuteUsage option for the current query in the Azure Cosmos DB service.
EnableCrossPartitionQuery Gets or sets a value indicating whether users are enabled to send more than one request to execute the query in the Azure Cosmos DB service. More than one request is necessary if the query is not scoped to single partition key value.
EnableLowPrecisionOrderBy Gets or sets the option to enable low precision order by in the Azure Cosmos DB service.
EnableScanInQuery Gets or sets the option to enable scans on the queries which couldn't be served as indexing was opted out on the requested paths in the Azure Cosmos DB service.
MaxBufferedItemCount Gets or sets the maximum number of items that can be buffered client side during parallel query execution in the Azure Cosmos DB service. A positive property value limits the number of buffered items to the set value. If it is set to less than 0, the system automatically decides the number of items to buffer.
MaxDegreeOfParallelism Gets or sets the number of concurrent operations run client side during parallel query execution in the Azure Cosmos DB service. A positive property value limits the number of concurrent operations to the set value. If it is set to less than 0, the system automatically decides the number of concurrent operations to run.
MaxItemCount Gets or sets the maximum number of items to be returned in the enumeration operation in the Azure Cosmos DB service.
PopulateQueryMetrics Gets or sets the PopulateQueryMetrics request option for document query requests in the Azure Cosmos DB service.
RequestContinuation Gets or sets the request continuation token in the Azure Cosmos DB service.
ResponseContinuationTokenLimitInKb Gets or sets the ResponseContinuationTokenLimitInKb request option for document query requests in the Azure Cosmos DB service.
PartitionKeyValue Sets the partition key as required by https://docs.microsoft.com/en-us/dotnet/api/microsoft.azure.documents.client.feedoptions.partitionkey?view=azure-dotnet

You can also use the 'With---' methods of the collections to set the properties.

Stored procedures and user-defined functions

Both the static and the dynamic drivers support stored procedures and user defined functions (though a little differently).

First off, they are listed in the browser window:

Second, you can run an sp if you want either by typing the call manually, or right-clicking the sp name in the browser and importing the call into the editor window. The results are then displayed in a table form:

Parameters are also supported.

Since the results of the sp are loaded into memory, you can go ahead and use Linq-to-objects to query your data.

If you use the dynamic driver, you don't really need to do anything. If you use the static driver, you have to create a method with the name of the SP that returns IQueryable (T is your type that you are querying) and inside the method call the CreateStoredProcedure() method (you can check out the Github sample for more). UDFs are also supported — you can run them as an SQL query (see below).

And the nice addition: if you hover over an sp or udf, you can check out their code:

SQL support

Here's the coolest of all: if you change your language to SQL, you can run DocumentDB sql queries directly from LinqPad and see the results in the table.

The syntax is almost entirely coherent with that of DocumentDb. The only difference is that you have to first specify the collection, against which you'd like to run the query (note that cross-collection queries are not supported, so this is not really a problem).

SQL support in the C# windows

You can execute raw SQl queries from the C# statements and C# expression windows as well using the ExecuteSql<dynamic>() method if you use the dynamic driver, or ExecuteSql<T> if you use the static driver:

Clone this wiki locally