Last month, the . This release brings the Table SDK in line with other and they use the specific Azure Core packages for handling requests, errors and credentials. Azure SDK team released a new library for Azure Tables for .NET, Java, JS/TS, and Python Azure SDKs 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. Azure Cosmos DB provides a Table API 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 command: dotnet 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 package: Azure.Data.Tables Connecting to our Table Client and Creating a table 🔨 The SDK provides us with two clients to interact with the service. A is used for interacting with our table at the account level. TableServiceClient We do this for creating tables, setting access policies, etc. We can also use a . This is used for performing operations on our entities. We can also use the to create tables like so: TableClient TableClient 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 When we run this code for the first time, we can see that the table has been created in our Data Explorer: Defining our entity 🧾 In Table Storage, we create entities in our table that require a and a . The combination of these needs to be unique within our table. Partition Key Row Key Entities have a set of properties and strongly-typed entities need to extend from the 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. ITableEntity For this tutorial, I'm going to use the above-mentioned properties along with two string properties (Email and PhoneNumber) to make up a type. CustomerEntity 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 method to insert it: .AddEntityAsync() CustomerEntity customerEntity = new CustomerEntity() { PartitionKey = "Velida", RowKey = "Will", PhoneNumber = "0123456789", Email = "will@test.com" }; await tableClient.AddEntityAsync(customerEntity); Heading back into our Customers table in Cosmos DB, we can see that the entity was successfully inserted. 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, Transactions can perform a mixture of create, delete, update and upsert operations. they will all fail! 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 objects that I'm going to insert into my table as a batch create operation. CustomerEntity We then create a new List of type and add the list of entities we want to include in the batch operation to it. We then use the method to submit the batch operation: TableTransactionAction .SubmitTransactionAsync() 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 = "jan@test.com" } }; 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: 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 filters can be a pain, but the SDK provides a helper library that makes it a bit easier. Using , we can write our OData query like so: OData query .CreateQueryFilter() 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 and like so: PartitionKeys RowKeys We can also use LINQ expressions to query our Table. Here, I'm using a LINQ query to retrieve a with a value of "Will": CustomerEntity RowKey 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: Deleting an entity ❌ Deleting entities from our table is just a simple call. All we need to do is pass in our and value like so: .DeleteEntityAsync() ParitionKey RowKey await tableClient.DeleteEntityAsync(partitionKey, "Will"); Checking our table, we can see that our entity has been successfully deleted: 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 and ! this blog post 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