Question

I have an MVC 4 site up and running. For now I have been using localDB and I want to change this so that everything is read from and written to Azure Table Storage.

This is not that hard to do, but it rises a design question for me: I don't want to implement TableServiceEntity directly on my model for 2 reasons:

  • I have business wise properties like ID and I don't want to have the rowkey / partition key fields to replace them (or have them duplicate the values in there)
  • And most importantly: one does not want the models to know where they are written to (that should be hidden from the models)

So the question is: what is the best approach here? (use DTO / automapper / ... ?)

Kind regards,

Was it helpful?

Solution

A couple notes about your scenario and Azure tables

  1. Take a look at the 3.0 release of the client which has dramatic performance improvements for tables, including JSON light /nometadata
  2. I highly recommend utilizing the Table service layer which provides the TableEntity, ITableEntity, and DynamicTableEntity types.

You have a few options here, the first is to use the TableEntity object and customize the serialization by overriding ITableEntity.Read/Write entity. This will allow you to change property names / values etc during serialization / deserialization.

You can also use a DTO type as you mentioned, but then you must maintain the object separately etc. In this teched talk at ~40:30 I demonstrated how to use a generic EntityAdapter class to directly persist 3rd party objects that did not Derive from TableEntity or implement the ITableEntity interface. (You can find the source of the examples here.) This approach would allow you to persist any object type to Azure Tables without exposing any dependency on storage itself.

OTHER TIPS

I have implemented the table storage for one of my Repositories and I got it working. There is one more thing though.

I notice a note in your sample code mentioning something about putting in a where clause. This is a method that I use in the repository that gets a collection of Benificiary records:

IQueryable<Benificiary> retrievedBenificiaries = (from entry in table.CreateQuery<DynamicTableEntity>() select entry).Resolve(EntityAdapter.AdapterResolver<Benificiary>);

So this returns an IQueryable<Benificiary> and in my controller that receives it, I want to do the following:

    public ActionResult Edit(int id = 0)
    {
        Benificiary benificiary = benificiaryRepository.GetAll().Where(b => b.BenificiaryID == id).First();
        if (benificiary == null)
        {
            return HttpNotFound();
        }

        return View(benificiary);
    }

But the Where clause pops up an error :

{"Expression of type 'System.Linq.IOrderedQueryable1[Microsoft.WindowsAzure.Storage.Table.DynamicTableEntity]' cannot be used for parameter of type 'System.Linq.IQueryable1[HomeConstructionManager.Models.Benificiary]' of method 'System.Linq.IQueryable1[HomeConstructionManager.Models.Benificiary] Where[Benificiary](System.Linq.IQueryable1[HomeConstructionManager.Models.Benificiary], System.Linq.Expressions.Expression1[System.Func2[HomeConstructionManager.Models.Benificiary,System.Boolean]])'"}

The only thing that I did to make it work was first doing the ToList and apply the where clause then.

Benificiary benificiary = benificiaryRepository.GetAll().ToList<Benificiary>().Where(b => b.BenificiaryID == id).First();

Should I do this like this or is there a better way to do this?

Also, I noticed that when I use the EntityAdapter, it nicely fills the rowkey and partition key but the properties still exists so it is stored double in the storage table.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top