RIA Services and Windows Azure Table Storage

We worked right up to the deadline, but I’m happy to say we got a preview of RIA support for Windows Azure Table Storage into the October Toolkit release (that coincides with the SP1 Beta release). You could integrate with table storage previously, but our goal was to make using it as simple as possible. With all the great new Azure features coming down the pipe (announced at PDC10), we want to give you first-class experience using table storage with WCF RIA Services.

Where to Start?

If you’re new to Windows Azure (and to tell the truth, we all fall in that bucket) then you need to start with Jim Nakashima’s blog. I always refer back to it, and it’s proved an invaluable resource. For an introduction to table storage, this post is a good start. The difference between Jim’s approach and what I’ll show here are the steps we take to integrate with existing DomainService patterns. Without further introduction, I’ll jump into the things you need to know to get the most out of our Microsoft.ServiceModel.DomainServices.WindowsAzure assembly preview.

Let’s Get a Project Set Up

We’ll use this section to go step-by-step and set up a clean Silverlight project ready for Azure. If you’re interested in starting with the Business Application Template instead, take a look at this introductory post.

1) Make sure you have the latest Windows Azure SDK installed (http://www.microsoft.com/windowsazure/)

2) Open Visual Studio and create a new Silverlight project with WCF RIA Services enabled

3) Add a Windows Azure Cloud Service project to your solution. When the New Cloud Service Wizard pops up, select ‘Ok’.

4) In your Cloud Service project, Add a Web Role Project from your solution.


In the Wizard, select your Web Application project.


5) The next step is to add the RIA Services reference you need to your Web Application project. My favorite way to do this is to add an empty DomainService using the wizard and then immediately delete it.


6) Finally, we need to make sure our application can be deployed by setting the RIA Services references to ‘Copy Local = True’.


In your web project, make sure to update the reference to both System.ServiceModel.DomainServices.Hosting and System.ServiceModel.DomainServices.Server.

7) Now that we’re ready to go, let’s add the references we’ll need to work with Windows Azure. Add references to System.Data.Services.Client, Microsoft.WindowsAzure.ServiceRuntime, Microsoft.WindowsAzure.StorageClient, and Microsoft.ServiceModel.DomainServices.WindowsAzure to your Web Application project.

You’ll also need to set Copy Local to True for both Microsoft.WindowsAzure.StorageClient and Microsoft.ServiceModel.DomainServices.WindowsAzure.

A Windows Azure Entity

Now that we have a project set up, we can focus on using Windows Azure Table Storage. Windows Azure provides queryable structured storage. You can create an unlimited number of tables which in turn can have an unlimited number of entities. There are a few constraints to the structure, but it’s pretty flexible (for more information take a look at the Table Storage whitepaper). One hard rule is that every entity must have three properties, the PartitionKey, the RowKey and the Timestamp. Together these form a unique key for an entity. Additionally, query results are returned sorted by PartitionKey and then by RowKey.

To make it as simple as possible to define entities, we’ve provided the base class TableEntity that includes these properties. The first step to working with table storage is to define your entity. For this post, we’re starting from scratch and the properties on our entity will define the schema of our table.

  public class MyEntity : TableEntity
    public string MyName { get; set; }

With this small snippet, I’ve defined an entity with four properties; PartitionKey, RowKey, Timestamp, and MyName. Now with an entity in hand, we’ll look at defining a context for working with table storage.

A Context for Table Storage

The second step for getting running with Windows Azure Table Storage is to create a context the DomainService can use. We wanted to create a familiar feel for developers used to working with RIA, so we’ve provided you with two types TableEntitySet and TableEntityContext.

  public class MyEntityContext : TableEntityContext
    public MyEntityContext() : 
GetConfigurationSettingValue("DataConnectionString")) { } public TableEntitySet<MyEntity> MyEntities { get { return base.GetEntitySet<MyEntity>(); } } }

In the snippet above, we reference a connection string specified in the Web Role configuration. To add a connection string, open the Web Role properties.



Now, with a small snippet of code, we’re ready to write our DomainService.

A Table Storage Domain Service

With our entity defined and our context ready, we can begin to write a DomainService. Once again, we’ve provided you with a base class to start with. The TableDomainService takes care of a lot of the table-storage-specific concerns so you can concentrate on your business logic.

  public class MyDomainService : TableDomainService<MyEntityContext>
    public IQueryable<MyEntity> GetMyEntities()
      return this.EntityContext.MyEntities;

    public void AddMyEntity(MyEntity entity)

    public void DeleteMyEntity(MyEntity entity)

    public void UpdateMyEntity(MyEntity entity)

For this sample, I just stubbed out simple CRUD operations. This is only a start, but we’ve now completed everything that’s required to get you up and running with a DomainService that reads and writes to table storage.

The Best Part

The best part is that once you have written your DomainService, all the RIA things you’re familiar with just work. You get change tracking. You get validation. You get the works. For instance, this small snippet uses a DomainDataSource to hook a DataGrid up to your DomainService.

  <UserControl  >

    <StackPanel >
      <dds:DomainDataSource ElementName="myEntitiesDDS" QueryName="GetMyEntitiesQuery">
          <web:MyDomainContext />
</dds:DomainDataSource> <sdk:DataGrid ItemsSource="{Binding ElementName=myEntitiesDDS, Path=Data}" />
</StackPanel> </UserControl>

This post was just a brief intro, but there was a lot of area to cover. In the next couple of weeks, I’ll try to flesh out some of the scenarios where things get a little more interesting. Also, if there are any Azure-related topics you’re curious about or want to see covered, just let me know and I’ll try to include them.

Comments (27)

  1. jamesstill says:

    So does the table storage context manage CloudStorageAccount under the covers? What about using CreateTableIfNotExist? Any documentation out there? I can add entities no problem but cannot query.

  2. kylemc says:

    It's taken care of in the TableEntitySet, but I've considered making it more obvious in the future. From what I've seen, there might be issues with development storage if you tables don't exist, but they don't translate to the cloud. For complex queries, add a dummy entity to development storage (if it's empty) to give it structure. Also, There are a number of LINQ operations that are only partially supported in Table storage (here's the list msdn.microsoft.com/…/dd135725.aspx). Some operations (like sorting) you'll have to do locally (this.EntityContext.MyEntities.ToArray()…).

  3. kylemc says:

    *sigh* Just found a major bug in the October Tookit. Guess you won't be able to use this with the DDS (or otherwise sort from the client). I'm working to get a Toolkit refresh out there.

  4. jamesstill says:

    After a very frustrating week I'm looking at alternatives. I don't think Azure is ready for prime time. I went through various scenarios with RIA Services and the MVC 2 template. Judging from the confusion online I don't think it's just me. So tonight I tried something very very basic: I created a cloud hosting service with an ASP.NET web role. Then added a SL 4 client using the navigation project template. Added a Silverlight-enabled WCF service to the web role and returned a "hello" string from the DoWork() operation. Struggled for 3 hours tonight with a SecurityException. ClientAccessPolicy.xml did no good. I finally removed the cloud service project and it then worked like a champ. All my legacy and new RIA service apps work great until I get involved with the app fabric and table storage on the back end. We're a .NET shop and I want to get our org into the cloud rather than support the buildout of a new data center. But I honestly can't back such a move right now. The devs need a very stable environment and we can't have a deployment nightmare going into UAT. Maybe in a year or so this will stabilize. While I'm at it I'm getting rid of TFS 2010 in our org too and putting us on svn. The workflow build tool is a complete disaster. I doubt anyone up there in Redmond is dogfooding that one. After several days of wasted effort we finally gave up and installed cruisecontrol with the TFS contrib and I got our build running in 2 hours. I'm not dumping on you Kyle, your blog is great, but someone up there has got to realize that those of us down here in the trenches need tools that work out of the box without special tweaks and endless blog-searching sessions to find hidden tips and tricks. Azure development has a smell for me and it feels too fragile. Ok sorry rant over. lol

  5. kylemc says:


    Harsh words, but in some measure deserved. I've been able to get my RIA projects running fine, but there was a bit of a learning curve. I've found work on Azure forced me to learn how to use IntelliTrace (which is a great tool BTW). It's the only way I've been able to nail down issues in my deployed applications. From what I've heard, the next version of the Azure tools will have a lot of new features to streamline some of this as well. I'm not sure when they come out, but maybe check back in half a year instead.

  6. clemg says:

    I am able to add entities, but when I call the base.GetEntitySet<MyEntity>() in my TableEntityContext, the TableEntitySet is always empty.  However, if use base.CreateQuery<MyEntity>("MyEntity") it correctly returns all entities added to the table.  Are there any gotchas that are preventing the TableEntitySet from getting populated?

  7. kylemc says:


    Check out my newer post on PartitionKeys (blogs.msdn.com/…/windows-azure-table-partitionkey-options-for-tabledomainservices.aspx). By default, the query is optimized to filter on partition key, so the two snippets you show above are expected to behave differently.

  8. Snoopy says:


    Thanks for the post.  Are there any Channel 9 videos, etc. that can take me through this process?  I have a SL4 app, wrapped in a Cloud Service project and have deployed it successfully to Azure.  I'm even using the ASP.Net Membership and Role object on Azure to authenticate.  But I'm ready to use RIA to created the rest of my SL4 pages and am struggling where to start.  I really like the Channel 9 videos or those similar.  Once I get a Summary page (i.e. with grid) and a Detail page (i.e. Child-like form) to house detail information such that user's may update.  I should be cooking with gas.  Any thoughts?

    Appreciate it.

  9. kylemc says:


    I haven't seen any videos on the subject. It sounds like you've got the hard stuff out of the way. If you're using Entity Framework and SQL Azure, you can just set your connection string to the one provided in the SQL Azure portal and everything is the same as before. If you aren't using SQL Azure, consider using Windows Azure Table Storage, a feature I talk about in some of my more recent posts.

  10. Snoopy says:

    Thanks Kyle.  Yes, I forgot to mention, my desire is to use Table Storage, rather than SQL Azure.  I'll check out your recent posts.  

  11. gioCap says:

    is it possible that Microsoft.ServiceModel.DomainServices.WindowsAzure; don't exist with last versione of azure skd?

  12. kylemc says:


    It's part of the latest RIA toolkit release.


  13. gevalia says:


    As I am just starting out with RIA and Azure as well, I'd like to see this sample include odata and soap endpoints as well.



  14. kylemc says:


    There shouldn't be any difference running those endpoints in Azure. Take a look at Deepesh's post where he shows how to use the various endpoints.


    Also, make sure you remember to set CopyLocal to true for each of the RIA assemblies.

  15. gevalia says:


    I was a bit too optimistic on this. Tried to compile and I'm getting assembly version compat issues. Looks like the DomainServices assembly used is from azure sdk 1.3. I had to revert my system back to 1.2 because of nasty issues with 1.3 (there's quite a bit of chatter on issues with 1.3). Version 1.2 is sooo much more stable.

    This seems to be the way I want to go so I'll need to spend the weekend trying to get 1.3 to work. I'll take a look at that episode.

    Thanks for the help – and quick response!


  16. kylemc says:


    RIA works on 1.2 as well (though you'll have to look up the PDC10 release of the Toolkit to get v1.2-compatible build of the TableDomainService). Take a look at this series of posts to get you started.


  17. Jason says:

    Is there any way that you can create a shell project in VS2010 that hooks up Silverlight 4, WCF Ria Services, and Windows Azure (Table Storage) and post for download so that we can just start out with the raw plumbing hooked up?  Please 🙂

  18. Martin Sher says:

    I am trying to follow this code but get an error at public class MyDomainService : TableDomainService<MyEntityContext>

    The error is Inconsistent Accessibility: base class ….

    Any help?

  19. kylemc says:


    Sure, but I'll need more information. Usually inconsistent accessibility messages are pretty helpful.

  20. Martin says:

    The error is

    Error 1 Inconsistent accessibility: base class 'Microsoft.ServiceModel.DomainServices.WindowsAzure.TableDomainService<RiskAggregation.ClassLibrary.Web.WorkSpaceStorageContext>' is less accessible than class 'RiskAggregation.ClassLibrary.Web.WorkSpaceStorageRepository' C:UsersMartinDocumentsVisual Studio 2010ProjectsWindowsAzureRiskAggregatorCompRiskAggregation.ClassLibrary.WebWorkSpaceStorageWorkSpaceStorageRepository.cs 15 18 RiskAggregation.ClassLibrary.Web

  21. kylemc says:


    It looks like you context type (the generic parameter to TableDomainService) is internal while your WorkSpaceStorageRepository is public. You should either make the both internal or both public.

  22. Martin Sher says:

    Most probably a basic question. In the example above, instead of accessing the domain service directly from the view/xaml. How do I reference the domain service from the view model i.e. what object type my I create and domain service function call to get all my entities so that I can bind to a data grid.



  23. Martin says:


    Thanks for all your help.

    Do you know of any simple examples of accessing azure storage tables through RIA services using Silverlight MMVM?

  24. kylemc says:


    The great part about RIA Services is the same client pattern will work against any type of DomainService. For example, you can have one DS using Entity Framework and another using Table Storage and your client is blissfully ignorant. Feel free to just take a Table Storage sample (the DomainService side) and an MVVM sample (the SL side) and mash them together.

  25. Kyle – I'm just getting started with RIA and table services.  I need to dynamically bind the context to the azure storage account of the logged in user – so using the dataconnectionstring in the context constructor doesn't work.  Previously with the storage client api I've done something like:

           public MyContext(CloudStorageAccount account)

               : base(account)

           { }

    That doesn't seem to work with the TableEntityContext as I get errors  that the constructor must be parameterless when I compile.  What do you suggest?

    Thanks -Mark

  26. kylemc says:


    The constructor constraint is in TableDomainService, so you need to do two things to get this to work. First, add a parameterless constructor to your context (even if you don't intend it to be used). Second, override TableDomainService.CreateEntityContext to correctly call the constructor that takes a CloudStorageAccount.

    Here's the default implementation if you're interested.

           protected virtual TEntityContext CreateEntityContext()


               TEntityContext context = new TEntityContext();

               context.PartitionKey = this.PartitionKey;

               // Use batching semantics unless otherwise specified

               context.SaveChangesDefaultOptions = string.IsNullOrEmpty(this.PartitionKey) ?

                   SaveChangesOptions.None : SaveChangesOptions.Batch;

               return context;