paint-brush
How to Use C# Azure.Data.Tables SDK with Azure Cosmos DBby@willvelida
1,248 reads
1,248 reads

How to Use C# Azure.Data.Tables SDK with Azure Cosmos DB

by Will Velida1mJuly 10th, 2021
Read on Terminal Reader
Read this story w/o Javascript
tldt arrow

Too Long; Didn't Read

Azure SDK team released a new library for Azure Tables for.NET, Java, JS/TS, and Python. This release brings the Table SDK in line with other Azure SDKs and they use the specific Azure Core packages for handling requests, errors and credentials. In this article, I'll show you how we can perform simple operations against a. Cosmos DB Table API account using the new Azure.Data.Table C# SDK. The SDK provides us with two clients to interact with the service. We can also use the TableClient to create tables like so: tableClient.createIfNotExists().

Companies Mentioned

Mention Thumbnail
Mention Thumbnail

Coin Mentioned

Mention Thumbnail
featured image - How to Use C# Azure.Data.Tables SDK with Azure Cosmos DB
Will Velida HackerNoon profile picture

Last month, the Azure SDK team released a new library for Azure Tables for .NET, Java, JS/TS, and Python. This release brings the Table SDK in line with other Azure SDKs and they use the specific Azure Core packages for handling requests, errors and credentials.


Azure Cosmos DB provides a Table API offering that is essentially Azure Table Storage on steroids! If you need a globally distributed table storage service, Azure Cosmos DB should be your go-to choice.


If you're making a choice between Azure Cosmos DB Table API and regular Azure Table Storage, I'd recommend reading this article.


In this article, I'll show you how we can perform simple operations against a Azure Cosmos DB Table API account using the new Azure.Data.Table C# SDK.


Specifically, we'll go over:

  • Installing the SDK 💻
  • Connecting to our Table Client and Creating a table 🔨
  • Defining our entity 🧾
  • Adding an entity ➕
  • Performing Transactional Batch Operations 💰
  • Querying our Table ❓
  • Deleting an entity ❌


Let's dive into it!

Installing the SDK 💻

Installing the SDK is pretty simple. We can do so by running the following dotnet command:


dotnet add package Azure.Data.Tables


If you prefer using a UI to install the NuGet packages, we can do so by right-clicking our C# Project in Visual Studio, click on Manage NuGet packages and search for the Azure.Data.Tables package:


image

Connecting to our Table Client and Creating a table 🔨

The SDK provides us with two clients to interact with the service. A TableServiceClient is used for interacting with our table at the account level.


We do this for creating tables, setting access policies, etc.


We can also use a TableClient. This is used for performing operations on our entities. We can also use the TableClient to create tables like so:


TableClient tableClient = new TableClient(config["StorageConnection"], "Customers");
            await tableClient.CreateIfNotExistsAsync();


To create our Table Client, I'm passing in my storage connection string from Azure and the name of the table I want to interact with. On the following line, we create the table if it doesn't exist.


To get out Storage Connection string, we can do so from our Cosmos DB account under Connection String:


image

When we run this code for the first time, we can see that the table has been created in our Data Explorer:

image

Defining our entity 🧾

In Table Storage, we create entities in our table that require a Partition Key and a Row Key. The combination of these needs to be unique within our table.


Entities have a set of properties and strongly-typed entities need to extend from the ITableEntity interface, which exposes Partition Key, Row Key, ETag and Timestamp properties. ETag and Timestamp will be generated by Cosmos DB, so we don't need to set these.


For this tutorial, I'm going to use the above-mentioned properties along with two string properties (Email and PhoneNumber) to make up a CustomerEntity type.


public class CustomerEntity : ITableEntity
{
    public string PartitionKey { get; set ; }
    public string RowKey { get; set; }
    public string Email { get; set; }
    public string PhoneNumber { get; set; }
    public DateTimeOffset? Timestamp { get; set; }
    public ETag ETag { get; set; }
}

Adding an entity ➕

To add a new entity into our table, we need to instantiate it and simply call the .AddEntityAsync() method to insert it:


CustomerEntity customerEntity = new CustomerEntity()
{
     PartitionKey = "Velida",
     RowKey = "Will",
     PhoneNumber = "0123456789",
     Email = "[email protected]"
};

await tableClient.AddEntityAsync(customerEntity);


Heading back into our Customers table in Cosmos DB, we can see that the entity was successfully inserted.


image

Performing Transactional Batch Operations 💰

The table service allows us to make multiple operations within a single batch request.


Transactions are 'all-or-nothing', meaning that if one operation in our batch fails, they will all fail! Transactions can perform a mixture of create, delete, update and upsert operations.


Just take note that all operations within a transaction need to target the same partition key.

In the code snippet below, I'm creating a list of CustomerEntity objects that I'm going to insert into my table as a batch create operation.


We then create a new List of type TableTransactionAction and add the list of entities we want to include in the batch operation to it. We then use the .SubmitTransactionAsync() method to submit the batch operation:


string partitionKey = "Velida";
List<CustomerEntity> familyList = new List<CustomerEntity>
{
      new CustomerEntity
      {
            PartitionKey = partitionKey,
            RowKey = "Don",
            PhoneNumber = "0987612345"
      },
      new CustomerEntity
      {
            PartitionKey = partitionKey,
            RowKey = "Jane",
            PhoneNumber = "0987612345"
      },
      new CustomerEntity
      {
            PartitionKey = partitionKey,
            RowKey = "Jan",
            PhoneNumber = "0987601298",
            Email = "[email protected]"
      }
};

List<TableTransactionAction> addFamilyBatch = new List<TableTransactionAction>();

addFamilyBatch.AddRange(familyList.Select(f => new TableTransactionAction(TableTransactionActionType.Add, f)));

Response<IReadOnlyList<Response>> response = await tableClient.SubmitTransactionAsync(addFamilyBatch);


Heading back into our table, we can see the entities that have been successfully inserted into our Table:


image

Querying our Table ❓

We can query our data in Table storage in a couple of ways. The code snippet below uses a OData expression.


Working with OData query filters can be a pain, but the SDK provides a helper library that makes it a bit easier. Using .CreateQueryFilter(), we can write our OData query like so:


Pageable<TableEntity> oDataQueryEntities = tableClient.Query<TableEntity>(filter: TableClient.CreateQueryFilter($"PartitionKey eq {partitionKey}"));

foreach (TableEntity entity in oDataQueryEntities)
{
    Console.WriteLine($"{entity.GetString("PartitionKey")}:{entity.GetString("RowKey")}");
}


Running this code, we can see a concatenation of our entities PartitionKeys and RowKeys like so:


image

We can also use LINQ expressions to query our Table. Here, I'm using a LINQ query to retrieve a CustomerEntity with a RowKey value of "Will":


Pageable<CustomerEntity> linqEntities = tableClient.Query<CustomerEntity>(customer => customer.RowKey == "Will");

foreach (var entity in linqEntities)
{
     Console.WriteLine($"{entity.RowKey} {entity.PartitionKey}");
}


When this code runs, we can see our entity printed out to us:


image

Deleting an entity ❌

Deleting entities from our table is just a simple .DeleteEntityAsync() call. All we need to do is pass in our ParitionKey and RowKey value like so:

await tableClient.DeleteEntityAsync(partitionKey, "Will");

Checking our table, we can see that our entity has been successfully deleted:

image

Wrapping up

Hopefully, after reading this article, you understand that working with the Azure.Data.Tables SDK is pretty straightforward. I like the approach that the Azure SDK team is taking with making its SDKs more consistent with each other.


Using the Azure.Data.Tables SDK, we can build applications that work with both Azure Cosmos DB table storage and regular table storage, so if you find that you're building an application using regular Table Storage and you're struggling with scale, you can switch to Cosmos DB without any code changes!


If you want to learn more about the Azure.Data.Tables library, check out this blog post and this GitHub repo!


Hopefully, you found this article useful! As always, if you have any questions, feel free to comment below or ask me on Twitter!


Happy Coding! 💻👨‍💻👩‍💻


Also published on https://dev.to/willvelida/using-the-new-c-azure-data-tables-sdk-with-azure-cosmos-db-20dd.