Using Azure Table Storage from within CRM

In my last article I described a scenario in which large amounts of data were moved from CRM to Azure Table Storage. The idea behind this operation is to offload inactive data to an alternate storage, keeping it accessible and keeping CRM lean and mean.

Today I had too much time to waste, so I started to experiment. The goal of the experiment was to find out if Azure Table Storage can be hooked up easily to CRM.

In this article I’ll share the things I learned from this exercise.

For this experiment I decided to write a useless plugin that is triggered by the RetrieveMultiple message on the account entity. All records fetched are written to Azure Table Storage. * why?  don’t ask *

The things that I had to investigate were:

  • How do I manage my Azure account?
  • What tools can I use?
  • How do I write to Azure Table Storage?
  • How can I retrieve data from it?
  • How do I integrate the Azure code in my plugin?

Managing the Azure Account

When logging in to Azure, you can use two different URL’s.

Once logged in, you get a nice overview in which on the left a menu bar is shown, containing all areas that you can manage. On the right side you’ll see the contents of a specific area.
In the menu bar you can see per area how many services are present.

Azureaccount1

In the menu bar I choose storage, I already created a storage account that I’m going to use for my experiment.  When you click the arrow behind the storage name, you’ll end up in the next screen…

Azureaccount2

… giving you total control over the storage account.

In order to see what data you have stored in the Azure Table Storage, you can download the  “Azure Storage Explorer”. A simple to use “explorer” tool in which you can inspect and modify your table storages.

Azureaccount3

In the bottom of the screen (see picture below), you’ll find an “Add” button (the big +), that you can use to add a new storage account. You can make as many storage accounts as required.
Furthermore you’ll find a button to manage your access keys. In order to connect to the Azure Table Storage, you’ll need to specify the Storage Account Name and the Access Key to make the connection (see picture below).

Azureaccount4

Connecting to Azure

When learning new techniques, I always start with a console application. The advantage is that you can focus on the technique itself without having to deal with constraints from an existing environment. Furthermore debugging is much much simpler.

After playing around it turned out that connecting to Azure is pretty straight forward. Once the basics were mastered, I took the plunge and implemented the Azure code in a plugin.

In order to be able to use Azure Table Storage, you have to add the NuGet package “Azure Table Storage” to your project.

For the proof of concept I ended up with two classes:

  • AzureAccount.cs
    In order to store data in Azure Table Storage, you need to work with a data class that inherits from “TableEntity”. This class has a required constructor with two parameters; PartitionKey and RowKey.
    The PartitionKey and RowKey are used to identify the data in the storage. It looks like a normal database key, but it works a bit differently.Table Storage is designed as a super fast storage engine. One way of achieving this is using load balancing data across storage nodes. In order to load balance the data efficiently, the partitionkey is used to store all data of the “partition” in a single storage node.
    This MSDN article explains the Table Service Data Model in a simple way.In the data class, you can define your own custom properties (in this example I implemented AccountId, Name and City).

AzureAccountClass

  • AccountPlugin.cs
    I implemented a simple plugin that handles the RetrieveMultiple message on the account entity. In case data is fetched from CRM, I set up a connection to Azure. I do this by calling the “CreateTable” method.In the “CreateTable” function I open the connection to Azure using a connection string containing the account name and the access key (see above).
    Once the connection is set up I try to get a reference to the Azure Storage table.  If the table does not exist, then it will be created.Once I have a reference to the Storage Table,  I start a batch operation, in which I create a new entity in the Storage table (using a single Partition Key —> we want to keep the data together, and a unique row key).
    After the batch operation has been build up, it is executed against the Storage table (for the sake of simplicity, I don’t use async methods).

Plugin

Test Run

Once the code was compiled, I uploaded the new plugin and registered a plugin step. Running the plugin for the first time resulted in the error below.

Ats1

In order to use the Azure functionality, you’ll need to use ILMERGE to merge the required assemblies with the plugin assembly.  Nicolas Nowinski wrote
a great blog article about using ILMERGE to merge DLLs for plugins.

The assemblies required to work with Azure Table Storage are:

  • Microsoft.WindowsAzure.Storage.dll
  • Microsoft.Data.OData.dll
  • Microsoft.Data.Edm.dll
  • Microsoft.Data.Services.Client.dll

Once these assemblies were merged, the plugin ran like a charm. Resulting in a new and populated table inside Azure table Storage.

Victory

Veni, vidi, vici!
“I came, I saw, I conquered” (Latin expression said by Julius Caesar regarding his military victories)

5 thoughts on “Using Azure Table Storage from within CRM

  1. Khadim Ali says:

    Great. Thanks for this.

  2. Ashley says:

    Can I ask which version of CRM/NuGet packages/Framework you’re building against? I’m having real issues getting this to work.

    I’m seeing ‘Microsoft.WindowsAzure.Storage.StorageException.GetObjectData(System.Runtime.Serialization.SerializationInfo, System.Runtime.Serialization.StreamingContext)’. Security accessibility of the overriding method must match the security accessibility of the method being overriden.Detail:

    As soon as I add the reference to my plugins project (CRM2016 online, 4.5.2, SDK8.0.0, AzureStorage NuGet 8.0.1) Thanks

Leave a Reply

Your email address will not be published. Required fields are marked *