2.5 Properties

2.5.1 Accessing a property

You access Azure Table Storage entity properties by either using by simply typing the property name, consider the following example where we get a entity that has a Salary and FullName property:

// Get a reference to Azure Table Storage
dynamic storage = new DynStorage("UseDevelopmentStorage=true");

// Get reference to the ExampleMessagesTable table, it's created if it doesn't already exist
dynamic employeesTable = storage.exampleEmployees;

// Get a reference to the  entity
var employee = employeesTable.Entity("Doe""Jane");

// Write Jane Doe's salary to the console
Console.WriteLine(employee.FullName + "'s salary is $" +  employee.Salary + " USD/yr");

Alternatively, if you have a string with the property name you can access the property by accessing the DynEntity class as a Key/Value dictionary, the following example uses this approach to achieve the same as the previous example:

// Get a reference to Azure Table Storage
dynamic storage = new DynStorage("UseDevelopmentStorage=true");

// Get reference to the ExampleMessagesTable table, it's created if it doesn't already exist
dynamic employeesTable = storage.exampleEmployees;

// Get a reference to the  entity
DynEntity employee = employeesTable.Entity("Doe""Jane");

// Write Jane Doe's salary to the console
Console.WriteLine(employee["FullName"].PropertyValue + "'s salary is $" + employee["Salary"].PropertyValue + " USD/yr");

In the example above a call to DynProperty.PropertyValue property is required to get the actual value as the dictionary returns DynProperty objects.

2.5.2 Adding or updating a property

With Slazure, you create Azure Table Storage entity properties automatically when accessing them, you must however always call DynEntity.Save() method on the entity object in question after one or more properties have been added or updated. The following example shows how we create a new employee entity for John Doe by calling the DynEntity.Save() method:

// Get a reference to Azure Table Storage
dynamic storage = new DynStorage("UseDevelopmentStorage=true");

// Get reference to the ExampleMessagesTable table, it's created if it doesn't already exist
dynamic employeesTable = storage.exampleEmployees;

// Define a new entity using an id
var employee = employeesTable.Entity("Doe_Jane");

// Add some values to the employee entity
employee.FullName = "John Doe";
employee.Salary = 60000;

// Save the new entity to the Azure Table Storage
employee.Save();

2.5.3 Listing properties

You list all entity properties by accessing DynEntity class as a Key/Value dictionary. In the following example all property names are listed for all entities that was returned from a Linq query:

public void EnumProperties()
{
    // Get a reference to the table
    dynamic storage = new QueryableStorage<DynEntity>("UseDevelopmentStorage=true");
    QueryableTable<DynEntity> table = storage.TestCustomers;

    // Build table query
    var queryResult = table.Where("SignedUpForNewsletter = true and Age < 22");

    foreach (DynEntity entity in queryResult)
    {
        foreach (KeyValuePair<string, IDynProperty> keyValuePair in entity)
        {
            Console.WriteLine(keyValuePair.Key);
        }
    }
}

3 Examples

3.1 Writing to a database

Get a reference to the Azure Table Storage with the DynStorage and from it you can access any table by its literal name. In the example create a table called ExampleMessagesTable that will hold some messages. The person that sent the message is identified by his/her IP-address and each message has a unique Guid to identity it. The CreateMessages() is the main entry point for creating messages with your class.

public static void CreateMessages()
{
    // Get a reference to the Table Service storage
    dynamic storage = new DynStorage("UseDevelopmentStorage=true");

    // Get reference to the ExampleMessagesTable table, it's created if it doesn't already exist
    dynamic messagesTable = storage.ExampleMessagesTable;

    AddMessage(messagesTable, "127.0.0.1"new Guid("1539964a-db24-46ba-8410-a91a2ed440b1"), 
        "Dr. Livingstone, I presume?");
    AddMessage(messagesTable, "192.168.1.100"new Guid("31F5E279-64EA-4796-8185-E75F3820D5ED"), 
        "Yes, and I feel thankful that I am here to welcome you.");
}

/// <summary>
/// Add a new message to the data Table Service storage
/// </summary>
static void AddMessage(dynamic messagesTable, string ipAddress, Guid messageId, string message)
{
    // Create an entity in the ExampleMessagesTable table using the IP address as the PartitionKey and the message ID as RowKey.
    var messageEntity = messagesTable.Entity(ipAddress, messageId.ToString());
    messageEntity.Message = message;

    // Save the entity to the Azure Table Service storage
    messageEntity.Save();
}

3.2 Querying a database using the Slazure object model

There are two ways of querying entities with Slazure; using the Slazure object model and using the Slazure LINQ provider. Firstly, let’s look at querying for entities with the Slazure object model. In the example below a call the ShowMessage() method would display the text "Dr. Livingstone, I presume?" in the console by simply referencing the entity using the IP-address and message ID.

// Query for and display the message "Dr. Livingstone, I presume?"
public static string ShowMessage()
{
    // Get a reference to the Table Service storage
    dynamic storage = new DynStorage("UseDevelopmentStorage=true");

    // Get reference to the ExampleMessagesTable table, it's created if it doesn't already exist
    dynamic messagesTable = storage.ExampleMessagesTable;

    // Query for and display the message "Dr. Livingstone, I presume?"
    Console.WriteLine(MessageObjectModelQuery(messagesTable, "127.0.0.1"new Guid("1539964a-db24-46ba-8410-a91a2ed440b1")));
}

static string MessageObjectModelQuery(dynamic messagesTable, string ipAddress, Guid messageId)
{
    // Get a reference to an message entity using IP as the PartitionKey and message id as RowKey
    var messageEntity = messagesTable.Entity(ipAddress, messageId.ToString());

    return "Message=" + messageEntity.Message;
}

3.2.1 Slazure object model query optimizing

Each call to MessageObjectModelQuery() above makes a single database I/O operation to retrieve the Message property only, but what if there were two properties like below?

/// <summary>
/// Add a new message to the data Table Service storage
/// </summary>
static void AddMessage(dynamic messagesTable, string ipAddress, Guid messageId, string message, int messageNumber)
{
    // Create an entity in the ExampleMessagesTable table using the IP address as the PartitionKey and the message ID as RowKey.
    var messageEntity = messagesTable.Entity(ipAddress, messageId.ToString());
    messageEntity.Message = message;
    
    // Iterative message number sent from the IP-sddress
    messageEntity.Number = messageNumber;

    // Save the entity to the Azure Table Service storage
    messageEntity.Save();
}

static string MessageObjectModelQuery(dynamic messagesTable, string ipAddress, Guid messageId)
{
    // Get a reference to an message entity using IP as the PartitionKey and message id as RowKey
    var messageEntity = messagesTable.Entity(ipAddress, messageId.ToString());

    return "Message=" + messageEntity.Message + ", Number=" + messageEntity.Number;
}

In the case like above then each call to MessageObjectModelQuery() would mean two database I/O operations; one for each property read, which is of course wasteful of I/O resources. Fortunately, Slazure has a solution for this problem by using the DynEntity.LoadSome() method like in the example below where both the Message and MessageNumber properties are queried from the storage with just a single I/O operation:

static string MessageObjectModelQuery(dynamic messagesTable, string ipAddress, Guid messageId)
{
    // Get a reference to an message entity using IP as the PartitionKey and message id as RowKey
    var messageEntity = messagesTable.Entity(ipAddress, messageId.ToString());
    var columnsToLoad = new List<string> { "Message""Number" };
    messageEntity.LoadSome(columnsToLoad);
    return "Message=" + messageEntity.Message + ", message number=" + messageEntity.Number;
}

Slazure also has a DynEntity.LoadAll() function which retrieves all the entity properties in a single I/O operation:

static string MessageObjectModelQuery(dynamic messagesTable, string ipAddress, Guid messageId)
{
    // Get a reference to an message entity using IP as the PartitionKey and message id as RowKey
    var messageEntity = messagesTable.Entity(ipAddress, messageId.ToString());
    messageEntity.LoadAll();
    return "Message=" + messageEntity.Message + ", message number=" + messageEntity.Number;
}

3.3 Querying the database using the Slazure LINQ Provider

That’s the main things to consider when querying with the Slazure object model, now let’s look at achieving the same with the Slazure LINQ provider. In the example below we access the Azure Table Storage using the QueryableStorage<T> class this time; this is the data storage class that the Slazure LINQ Provider uses, and DynEntity is the base class for dynamically typed entities:

// Query for and display the message "Dr. Livingstone, I presume?"
public static void ShowMessageWithLINQ()
{
    // Get a reference to the Microsoft Azure table service storage
    dynamic queryableStorage = new QueryableStorage<DynEntity>("UseDevelopmentStorage=true");
    QueryableTable<DynEntity> queryableMessagesTable = queryableStorage.ExampleMessagesTable;

    Console.WriteLine(MessageLinqQuery(queryableMessagesTable, "127.0.0.1"new Guid("1539964a-db24-46ba-8410-a91a2ed440b1")));
}

// Query for a message using the Slazure LINQ provider
static string MessageLinqQuery(IQueryable<DynEntity> messagesTable, string ipAddress, Guid messageId)
{
    var messageQuery =
        messagesTable.Where("PartitionKey = @0 && RowKey = @1", ipAddress, messageId.ToString())
        .Select("new(Message)");

    dynamic messageEntity = messageQuery.Cast<dynamic>().First();

    return "Message=" + messageEntity.Message + ", message number=" + messageEntity.Number;
}

3.3.1 Slazure LINQ Provider query optimizing

The above example would create two I/O operations since only Message is defined in the Select() query projection, by adding the Number property to the query projection you would fetch both entity properties in a single I/O operation:

// Query for a message using the Slazure LINQ provider
static string MessageLinqQuery(IQueryable<DynEntity> messagesTable, string ipAddress, Guid messageId)
{
var messageQuery =
    messagesTable.Where("PartitionKey = @0 && RowKey = @1", ipAddress, messageId.ToString())
    .Select("new(Message, Number)");

    dynamic messageEntity = messageQuery.Cast<dynamic>().First();

    return "Message=" + messageEntity.Message + ", message number=" + messageEntity.Number;
}