So far, we have been working with different web-based and GUI tools to interact with the Cosmos DB service and a document database with the SQL API. We have been using a single partition and the default indexing options. Now we will leverage our existing Cosmos DB knowledge to perform the different operations we learned with the Cosmos DB .NET Core SDK. In addition, we will work with a partition key and customized indexing options.
First, we will create an application that will work with dynamic documents without any schema by taking advantage of the dynamic keyword to create dynamic objects. The use of this keyword is one of a few possible approaches to interacting with Cosmos DB JSON documents in .NET Core and C#. The clear advantage of this approach is that we don't need to create a class that represents the documents just to perform a few operations with a collection. We will look at many common scenarios with the .NET Core SDK and then we will create a new version of the application that will use Plain Old CLR Objects (POCOs)—that is, classes that represent the documents—and that will allow us to take full advantage of working with LINQ queries against documents. Thus, we must keep in mind that the first version of our application won't represent best practices, but it will allow us to easily dive deep into the .NET Core SDK.
We will use Visual Studio 2017 as a baseline for the examples. However, you can also run the examples in Visual Studio Code in any of its supported platforms. You can work with the Azure Cosmos DB emulator or the Cosmos DB cloud-based service. Remember that the use of cloud-based services will consume credits and charges might be billed based on the Azure subscription you have.
We will stay focused on the different tasks with a Cosmos DB database, and therefore, we will create a .NET Core 2 console application. Then, we will be able to use the improved version of this application as a baseline for other future applications that require interaction with Cosmos DB, such as a RESTful web API, an ASP.NET Core MVC web application, a mobile app, or a microservice.
We will work with a few documents that represent eSports competitions, each with a unique title. Each document will include details about the competition location, the platforms that are allowed, the games that the players will be able to play, the number of registered competitors, the competition status, and its date and time. If the competition is either in progress or finished, the document will include data about the first three positions—that is, the winners—with details about their scores and prizes.
Our first version of the application will perform the following tasks:
- Create a new document database if it doesn't exist
- Create a new document collection with specific options if it doesn't exist
- Retrieve a document with a specific title
- Insert a document related to a competition that has finished and has winners
- Retrieve the number of documents with a specific title
- Insert a document related to a competition that is scheduled and doesn't have winners yet
- Retrieve a document related to a competition that is scheduled and update its date and its number of registered competitors
- Retrieve and display the titles for all the scheduled competitions that have more than 200 registered competitors
Make sure you have an Azure Cosmos DB account created in Azure Portal or the Cosmos DB emulator properly installed before trying to execute any of the next examples. We will use the same account with the SQL API we have created in the previous chapters. However, remember that you can decide to use the emulator.
The Microsoft.Azure.DocumentDB.Core NuGet package provides the client library for .NET Core to connect to Azure Cosmos DB through the SQL API. This package is essential for working with Cosmos DB in any .NET Core application. We will analyze some of the most important classes of Microsoft.Azure.DocumentDB.Core Version 2.0.0 before we start working on the first version of the application.
The following diagram shows the different resources that belong to a Cosmos DB account: a document database and a collection with the names of the class or classes of the Azure Cosmos DB client library, which will represent each resource below the resource name in bold. We will work with many of these classes in the first version of our application and in its next version. Note that the diagram is not a class diagram, and therefore, the arrows don't mean inheritance. The diagram shows the structure of the different resources and the classes that we will use to work with them:
The next table summarizes the information displayed in the previous diagram:
| Namespace | Class name | Description |
| Microsoft.Azure.Documents.Client | DocumentClient | This class allows us to configure and execute requests against a specific account of the Cosmos DB service. In this case, we will only work with accounts created with the SQL API. |
| Microsoft.Azure.Documents | DatabaseAccount | This class represents a database account with the SQL API; that is, the container for document databases. |
| Microsoft.Azure.Documents | Database | This class represents a document database with the SQL API within a Cosmos DB database account. |
| Microsoft.Azure.Documents | DocumentCollection | This class represents a document collection (the container) within a document database. |
| Microsoft.Azure.Documents | Document | This class represents a JSON document that belongs to a document collection. |
| Microsoft.Azure.Documents | StoredProcedure | This class represents a stored procedure written with the server-side JavaScript API. |
| Microsoft.Azure.Documents | Trigger | This class represents a trigger written in JavaScript. The trigger can be either a pre-trigger or a post-trigger. |
| Microsoft.Azure.Documents | Conflict | This class represents a version conflict resource. |
The following classes inherit from the Microsoft.Azure.Documents.Resource class:
- DatabaseAccount
- Database
- DocumentCollection
- Document
- StoredProcedure
- Trigger
- Conflict
The following lines show the definition for the Microsoft.Azure.Documents.Resource class:
using System; using Newtonsoft.Json; namespace Microsoft.Azure.Documents { public abstract class Resource : JsonSerializable { protected Resource(); protected Resource(Resource resource); [JsonProperty(PropertyName = "id")] public virtual string Id { get; set; } [JsonProperty(PropertyName = "_rid")] public virtual string ResourceId { get; set; } [JsonProperty(PropertyName = "_self")] public string SelfLink { get; } [JsonIgnore] public string AltLink { get; set; } [JsonConverter(typeof(UnixDateTimeConverter))] [JsonProperty(PropertyName = "_ts")] public virtual DateTime Timestamp { get; internal set; } [JsonProperty(PropertyName = "_etag")] public string ETag { get; } public T GetPropertyValue<T>(string propertyName); public void SetPropertyValue(string propertyName, object propertyValue); public byte[] ToByteArray(); } }
The use of JsonProperty(PropertyName = attribute followed by the name of the JSON key and a closing bracket maps a specific JSON key to the C# property, which has a different name. For example, the _rid JSON key will be available in the ResourceId property in an instance of the Document class. We learned about many of these properties in Chapter 2, Getting Started with Cosmos DB Development and NoSQL Document Databases, in the Understanding the automatically generated key-value pairs section. Specifically, we analyzed the automatically generated key-value pairs for a new document inserted in a collection. In this case, the generalized resources have fewer automatically generated values than a document. All the previously enumerated classes that represent Cosmos DB resources inherit the following standard resource properties defined in ...