Rasmus Christensen
Rasmus Christensen

Reputation: 8531

Preferred way to store a child object in Azure Table Storage

I did a little expirement with storing child objects in azure table storage today. Something like Person.Project where Person is the table entity and Person is just a POCO. The only way I was able to achieve this was by serializing the Project into byte[]. It might be what is needed, but is there another way around?

Thanks Rasmus

Upvotes: 0

Views: 1903

Answers (4)

Dogu Arslan
Dogu Arslan

Reputation: 3384

I have come across a similar problem and have implemented a generic object flattener/recomposer API that will flatten your complex entities into flat EntityProperty dictionaries and make them writeable to Table Storage, in the form of DynamicTableEntity.

Same API will then recompose the entire complex object back from the EntityProperty dictionary of the DynamicTableEntity.

Have a look at: https://www.nuget.org/packages/ObjectFlattenerRecomposer/

Usage:

//Flatten complex object (of type ie. Order) and convert it to EntityProperty Dictionary
 Dictionary<string, EntityProperty> flattenedProperties = EntityPropertyConverter.Flatten(order);

// Create a DynamicTableEntity and set its PK and RK
DynamicTableEntity dynamicTableEntity = new DynamicTableEntity(partitionKey, rowKey);
dynamicTableEntity.Properties = flattenedProperties;

// Write the DynamicTableEntity to Azure Table Storage using client SDK

//Read the entity back from AzureTableStorage as DynamicTableEntity using the same PK and RK
DynamicTableEntity entity = [Read from Azure using the PK and RK];

//Convert the DynamicTableEntity back to original complex object.
 Order order = EntityPropertyConverter.ConvertBack<Order>(entity.Properties);

Upvotes: 0

Shaun Xu
Shaun Xu

Reputation: 4656

Personally I would prefer to store the Project in a different table with the same partition key that its parent have, which is its Person's partition key. It ensures that the person and underlying projects will be stored in the same storage cluster. On the code side, I would like to have some attributes on top of the reference properties, for example [Reference(typeof(Person))] and [Collection(typeof(Project))], and in the data context class I can use some extension method it retrieve the child elements on demand.

Upvotes: 1

Jim O&#39;Neil
Jim O&#39;Neil

Reputation: 23764

In terms of the original question though, you certainly can store both parent and child in the same table - were you seeing an error when trying to do so?

One other thing you sacrifice by separating out parent and child into separate tables is the ability to group updates into a transaction. Say you created a new 'person' and added a number of projects for that person, if they are in the same table with same partition key you can send the multiple inserts as one atomic operation. With a multi-table approach, you're going to have to manage atomicity yourself (if that's a requirement of your data consistency model).

Upvotes: 0

knightpfhor
knightpfhor

Reputation: 9399

I'm presuming that when you say person is just a POCO you mean Project is just a POCO?

My preferred method is to store the child object in its own Azure table with the same partition key and row key as the parent. The main reason is that this allows you to run queries against this child object if you have to. You can't run just one query that uses properties from both parent and child, but at least you can run queries against the child entity. Another advantage is that it means that the child class can take up more space, the limit to how much data you can store in a single property is less than the amount you can store in a row.

If neither of these things are a concern for you, then what you've done is perfectly acceptable.

Upvotes: 0

Related Questions