Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Azure october 2012 sdk - how to delete a table entity without retrieving it first?

In the previous version we could do this to delete an entity without knowing whether it exists.

svc = new TestContext();
item = new TestEntity("item2pk", "item2rk");
svc.AttachTo("TestTable", item, "*");
svc.DeleteObject(item);
svc.SaveChanges();

(source)

The new TableOperations doesn't have this syntax. Do I have to use this old method or is there a way? I'd like to be consistent because now all my code use the new classes for version 2.

edit: the title was misleading

like image 687
David S. Avatar asked Nov 06 '12 17:11

David S.


2 Answers

You'll need to use TableOperation.Delete:

var storageAccount = CloudStorageAccount.DevelopmentStorageAccount;
var table = storageAccount.CreateCloudTableClient()
                            .GetTableReference("tempTable");
table.CreateIfNotExists();

// Add item.
table.Execute(TableOperation.Insert(new TableEntity("MyItems", "123")));

// Load items.
var items = table.ExecuteQuery(new TableQuery<TableEntity>());
foreach (var item in items)
{
    Console.WriteLine(item.PartitionKey + " - " + item.RowKey);
}

// Delete item (the ETAG is required here!).
table.Execute(TableOperation.Delete(new TableEntity("MyItems", "123") { ETag = "*" }));

The delete only works for entities that exist. Even though the old client had the ContinueOnError option, it was not compatible with the Batch operation (as explained here).

The only way to have a successful batch of Deletes if you don't know that the entity exists it to add them first (or replace them if they already exist):

var ensureItemsBatch = new TableBatchOperation();
ensureItemsBatch.InsertOrReplace(new MyEntity("MyItems", "123") { Active = false });
ensureItemsBatch.InsertOrReplace(new MyEntity("MyItems", "456") { Active = false });
ensureItemsBatch.InsertOrReplace(new MyEntity("MyItems", "789") { Active = false });
table.ExecuteBatch(ensureItemsBatch);

var deleteItemsBatch = new TableBatchOperation();
deleteItemsBatch.Delete(new MyEntity("MyItems", "123") { ETag = "*" });
deleteItemsBatch.Delete(new MyEntity("MyItems", "456") { ETag = "*" });
deleteItemsBatch.Delete(new MyEntity("MyItems", "789") { ETag = "*" });
table.ExecuteBatch(deleteItemsBatch);
like image 120
Sandrino Di Mattia Avatar answered Nov 15 '22 16:11

Sandrino Di Mattia


I use my own method which catches the StorageException which occurs when the entity doesn´t exist. Additionally it returns whether the entity was deleted as bool.

public bool DeleteTableEntity(string partitionKey, string rowKey)
{
    try
    {
        _table.Execute(TableOperation.Delete(new TableEntity(partitionKey, rowKey) { ETag = "*" }));
        return true;
    }
    catch (StorageException e)
    {
        if (e.RequestInformation.HttpStatusCode == (int)HttpStatusCode.NotFound)
            return false;
        throw;
    }
}

The _table member variable is of type CloudTable (Microsoft.WindowsAzure.Storage.Table.CloudTable). For this example I use the assembly Microsoft.WindowsAzure.Storage.dll, v2.1.0.3 installed with NuGet.

like image 45
huha Avatar answered Nov 15 '22 16:11

huha