CRUD Operations with Azure Table Storage in an Azure Function – D

In the previous part of this series we briefly described how to Create, Retreive and Update records in an Azure Table Storage using Azure Web Functions. In this part, we will look into final part of quadrant – the Delete operations.

As you would have guessed after going through previous posts in this series, we would be using the CloudTable for deletion of record.

[FunctionName("DeleteRecord")]
public static async Task<IActionResult> DeleteEntity(
    [HttpTrigger(AuthorizationLevel.Anonymous,"POST", Route = "DeleteRecord/{partitionKey}/{rowKey}")] HttpRequest request,
    [Table("todos", "{partitionKey}", "{rowKey}")] TodoTableEntity tableEntity,
    [Table("todos")] CloudTable todoTable,
    ILogger log)
{
    log.LogInformation("Request to delete the record");

    var deleteOperation = TableOperation.Delete(tableEntity);
    var result = await todoTable.ExecuteAsync(deleteOperation);
    return new OkObjectResult(result);
}

In this above example, we are using Bindings to retrieve the record to be deleted. The PartitionKey and RowKey is retrieved from the query string, quite similiar to the method we learned in the Retrieve record post.

A word of caution here. It is tempting to retrieve the record using RowKey alone, but one needs to be aware of the consequences. If one was to attempt retrival/deletion based on RowKey alone, the whole table has to be scanned for the record. Furthermore, it is theoratical to have the same RowKey over different patition (though this could be averted by application logic), which would retrieve multiple entites instead of one.

Deletion Table Binding

Of course, you could achieve the above without Table Binding.

[FunctionName("DeleteWithoutBinding")]
        public static async Task<IActionResult> DeleteWithoutBinding(
        [HttpTrigger(AuthorizationLevel.Anonymous, "post", Route = null)] HttpRequest request,
        [Table("todos")] CloudTable todoTable,
         ILogger log)
{
    log.LogInformation("Request to delete Record without binding");

    string partitionKey = request.Query["pkey"];
    string rowKey = request.Query["rkey"];

    var tableQuery = new TableQuery<TodoTableEntity>();

    var filterRowKeyAndPartitionKey = TableQuery.CombineFilters(
        TableQuery.GenerateFilterCondition(nameof(TodoTableEntity.RowKey), QueryComparisons.Equal, rowKey),
        TableOperators.And,
        TableQuery.GenerateFilterCondition(nameof(TodoTableEntity.PartitionKey), QueryComparisons.Equal, partitionKey));

    tableQuery.FilterString = TableQuery.CombineFilters(
        TableQuery.GenerateFilterCondition(nameof(TableEntity.PartitionKey), QueryComparisons.NotEqual, "Key"),
        TableOperators.And,
        filterRowKeyAndPartitionKey);

    var itemToDelete = todoTable.ExecuteQuery(tableQuery).First();

    var deleteOperation = TableOperation.Delete(itemToDelete);
    var deleteResponse = await todoTable.ExecuteAsync(deleteOperation);
    return new OkObjectResult(deleteResponse);
}

But honestly, I feel that is quite a lot of boilerplate code which could be avoided using bindings. I strongly suggest you use binding unless you have very strong reasons of doing otherwise.

Well, so far we have seen CRUD operations using the Azure Table Storage. In the next part of this series, we will explore another medium of storage provided by Azure. Until then, enjoy coding.