static void

Table Storage

NB: based on API v2

TableEntity

Entities are based on Microsoft.WindowsAzure.Storage.Table.TableEntity, which has a composite key based on string PartitionKey and string RowKey. All rows in one partition will live on one machine together.

Key strings must be maximum 1k length, and not include the characters \ / # ?

There is also a timestamp and 252 other properties, but they aren't easily searchable (in the new API- no more linq)

using System;
using Microsoft.WindowsAzure.Storage.Table;
 
namespace MartinWeb.Cloud
{
    public class LogEntry : TableEntity
    {
        public LogEntry()
        {
            //must have default ctor
            EventDate = DateTime.UtcNow;
            PartitionKey = EventDate.Date.ToString("yyyyMMdd");
            //ensure it is unique
            RowKey = EventDate.ToString("HHmmss") + Guid.NewGuid();
        }
 
        public LogEntry(DateTime eventDate, string message)
        {
            EventDate = eventDate;
            Message = message;
            PartitionKey = EventDate.Date.ToString("yyyyMMdd");
            //ensure it is unique
            RowKey = EventDate.ToString("HHmmss") + Guid.NewGuid();
        }
 
        public string Message { get; set; }
        //don't set the property (partitionKeys are fixed)
        public DateTime EventDate { get; set; }
    }
}

Store operations

Create a TableClient, then a CloudTable. The common operations:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Table;
 
namespace MartinWeb.Cloud
{
    public class TableStore<T> where T : TableEntity, new()
    {
        private readonly string _tableName;
 
        public TableStore(string tableName)
        {
            _tableName = tableName;
        }
 
        private CloudTable FindTable()
        {
            var connectionString =
                CloudConfigurationManager.GetSetting("StorageConnectionString");
            var storageAccount = CloudStorageAccount.Parse(connectionString);
            var tableClient = storageAccount.CreateCloudTableClient();
            var table = tableClient.GetTableReference(_tableName);
            table.CreateIfNotExists();
            return table;
        }
 
        public void Add(T entity)
        {
            var table = FindTable();
            var operation = TableOperation.Insert(entity);
            table.Execute(operation);
        }
 
        public void Add(ICollection<T> entities)
        {
            if (!entities.Any()) return;
 
            var partitionKey = entities.First().PartitionKey;
            if (entities.Any(x => x.PartitionKey != partitionKey))
                throw new InvalidOperationException("All entities in batch must have same partitiion key");
 
            var table = FindTable();
            var operation = new TableBatchOperation();
            foreach (var entity in entities)
            {
                operation.Insert(entity);
            }
            table.ExecuteBatch(operation);
        }
 
        public void Update(T entity)
        {
            var table = FindTable();
            var operation = TableOperation.Replace(entity);
            table.Execute(operation);
        }
 
        public void Delete(T entity)
        {
            var table = FindTable();
            var operation = TableOperation.Delete(entity);
            table.Execute(operation);
        }
 
        public T Get(string partitionKey, string rowKey)
        {
            var table = FindTable();
            var operation = TableOperation.Retrieve<T>(partitionKey, rowKey);
            var result = table.Execute(operation);
            return (T)result.Result; //could be null
        }
 
        public IEnumerable<T> Query(string partitionStart, string partitionEnd = null)
        {
            var table = FindTable();
            var filter =
                TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.GreaterThanOrEqual, partitionStart);
            if (!string.IsNullOrWhiteSpace(partitionEnd))
            {
                var end =
                    TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.LessThanOrEqual, partitionEnd);
                filter = TableQuery.CombineFilters(filter, TableOperators.And, end);
            }
            var query = new TableQuery<T>()
                .Where(filter);
 
            return table.ExecuteQuery(query);
        }
    }
}

Use:

var store = new TableStore<LogEntry>("LogEntries");
var entity = store.Get(pKey, rowKey);
store.Delete(entity);
store.Add(new LogEntry(new DateTime(2012, 10, 21, 23, 34, 9), "Error"));