The Azure Table service, provides a semi-structured storage in the form of tables that contain a collection of entities, these entities have primary keys and set of properties. A property is a name, typed-value pair.
Every entity in table storage has two key properties, Partition Key and the Row key which together uniquely identify each entity in the table.
The Table Service API is compliant with REST API provided by WCF Data Services. In order to use the WCF Data Services Client Library to access data in table storage, you need to create a context class that derives from TableServiceContext, which itself derives from DataServiceContext in WCF Data Services.
So to get started lets create a new project with Visual Studio with a web role.
Next we need to create a new project for the schema classes. To do this click on File –> Add –> New Project.
- Choose Class Library and give it a name I named mine LogSheet_Data
- Delete the default class file generated by the class library template.
- Add a reference to System.Data.Services.Client.
- Add another reference to Microsoft.WindowsAzure.StorageClient
- Now we are ready to define its schema. to do this add a new class to your project, I am going to name mine LogSheetEntry
- Add the namespace declaration to import the types from the two assemblies
using Microsoft.WindowsAzure.StorageClient;
- Update the declaration of the LogSheetEntry class to make it public and derive from the the TableServiceEntity class
public class LogSheetEntry
: Microsoft.WindowsAzure.StorageClient.TableServiceEntity
{
}
- TableServiceEntity is a class found in the Storage Client API. This class defines the PartititionKey, RowKey and TimeStamp system properties required by every entity stored in a Windows Azure table.
Together, the PartitionKey and RowKey define the DataServiceKey that uniquely identifies every entity within a table. - Add a default constructor then we need to initialize its PartitionKey and Row Key.
public LogSheetEntry()
{
PartitionKey = DateTime.UtcNow.ToString("MMddyyyy");
RowKey = string.Format("{0:10}_{1}", DateTime.MaxValue.Ticks - DateTime.Now.Ticks, Guid.NewGuid());
}
- To complete add the properties
public string Facility { get; set; }
public string AccountNum { get; set; }
- Next, you need to create the context class required to access the LogSheet table using WCF Data Services. To do this, in Solution Explorer, right-click the LogSheet_Data project, point to Add and select Class. In the Add New Item dialog, set the Name to LogSheetDataContext.cs and click Add.
- In the new class file, update the declaration of the new class to make it public and inherit the TableServiceContext class.
public class LogSheetDataContext
: Microsoft.WindowsAzure.StorageClient.TableServiceContext
- Now add a default constructor to initialize the base class with storage account information
public GuestBookDataContext(string baseAddress, Microsoft.WindowsAzure.StorageCredentials credentials)
: base(baseAddress, credentials)
{ }
- Add a property to the LogSheetDataContext class to expose the LogSheetEntry
public IQueryable<LogSheetEntry> LogSheetEntry
{
get
{
return this.CreateQuery<LogSheetEntry>("LogSheetEntry");
}
}
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.StorageClient;
public class LogSheetDataSource
{
private static CloudStorageAccount storageAccount;
private LogSheetDataContext context;
}
static LogSheetDataSource()
{
storageAccount = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
CloudTableClient.CreateTablesFromModel(
typeof(LogSheetDataContext),
storageAccount.TableEndpoint.AbsoluteUri,
storageAccount.Credentials);
}
- add a default constructor to initialize the data context class used to access table storage.
public LogSheetDataSource()
{
this.context = new LogSheetDataContext(storageAccount.TableEndpoint.AbsoluteUri, storageAccount.Credentials);
this.context.RetryPolicy = RetryPolicies.Retry(3, TimeSpan.FromSeconds(1));
}
- Next we will need a method that will return the contents of LogSheetEntry table
public IEnumerable<LogSheetEntry> GetLogSheetEntries()
{
var results = from g in this.context.LogSheetEntry
where g.PartitionKey == DateTime.UtcNow.ToString("MMddyyyy")
select g;
return results;
}
- We also are gong to need a method that will insert new entries
public void AddLogSheetEntry(LogSheetEntry newItem)
{
this.context.AddObject("LogSheetEntry", newItem);
this.context.SaveChanges();
}
- You guessed it we will need a method for an update, for simplicity, we are going to change the the facility only at this time.
public void UpdateImageThumbnail(string partitionKey, string rowKey, string Facility)
{
var results = from g in this.context.LogSheetEntry
where g.PartitionKey == partitionKey && g.RowKey == rowKey
select g;
var entry = results.FirstOrDefault<LogSheetEntry>();
entry.Facility = Facility;
this.context.UpdateObject(entry);
this.context.SaveChanges();
}
- Next steps is Creating a Web Role to Display the Time Sheet Entry and process User input, which is going to be in my next blog entry.