Save complex child entity in Cloud table azure storage

To learn how to work with complex object in cloud table, or to understand the how parent child relations among entities would be handled in azure cloud table, first we create some entities of customer, order and orderitem like example below.

using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Table;
using AzureTable = Microsoft.WindowsAzure.Storage.Table;
using ObjComposer=ObjectFlattenerRecomposer;

In earlier azure storage table example i have used cosmos table, but here to work with complex object we use Microsoft.WindowsAzure.Storage.Table instead of cosmos table.

using Microsoft.WindowsAzure.Storage.Table;

public class CustomerV1 : TableEntity
{                 
    public string Firstname { get; set; }
    public string Lastname { get; set; }
    public string Mobile { get; set; }
    public string Email { get; set; }
    public DateTime UpdateDT { get; set; }
     
    public OrderV1[] Orders { get; set; }
}

public class OrderV1 : TableEntity
{
    public string Title { get; set; }
    public DateTime DTime { get; set; }
    public decimal Total { get; set; }
    public OrderItem[] Items { get; set; }
}

public class OrderItem : TableEntity
{
    public string Iteam { get; set; }
    public int Qty { get; set; }
    public decimal UnitPrice { get; set; }
}

Now we create an instance of Customer class with an array property of order.

CustomerV1 _customer = new CustomerV1()
{
	Firstname = CustomerFirstName,
	Lastname = CustomerLastName,
	Mobile = Mobile,
	Email = Email,
	UpdateDT = DateTime.Now.ToUniversalTime(),
	Orders = GetOrders() // array of Order object
}; 

Now write a method to save data into azure storage table, previously we have already learned how to save simple data into cloud table, so here we focus what additional thing we do for saving data.

Cloud table does not support any parent child relation; here we save everything as one object as DynamicTableEntity.

We have to flatten the object; ObjectFlattenerRecomposer.Core.EntityPropertyConverter.Flatten(_customer); collection will be converted into array property, then set the flatten object as properties _dQuery.Properties = _fCustomer of DynamicTableEntity.

using Microsoft.WindowsAzure.Storage;
using Microsoft.WindowsAzure.Storage.Table;
using AzureTable = Microsoft.WindowsAzure.Storage.Table;
using ObjComposer=ObjectFlattenerRecomposer;

string _storageConnection = _configuration.GetSection("AzureStorage")["ConnectionString"];
var storageAccount = CloudStorageAccount.Parse(_storageConnection);
var tableClient = storageAccount.CreateCloudTableClient();

var customerTable = tableClient.GetTableReference("codTable");
await customerTable.CreateIfNotExistsAsync();

RowKeyThis = Guid.NewGuid().ToString();

CustomerV1 _customer = new CustomerV1()
{                     
    Firstname = CustomerFirstName,
    Lastname = CustomerLastName,
    Mobile = Mobile,
    Email = Email,
    UpdateDT = DateTime.Now.ToUniversalTime(),
    Orders = GetOrderList(CustomerFirstName, PartitionKeyThis)
};
var flatenObj = ObjectFlattenerRecomposer.Core.EntityPropertyConverter.Flatten(_customer);

DynamicTableEntity _dQuery1 = new DynamicTableEntity(PartitionKeyThis, RowKeyThis);
_dQuery1.Properties = flatenObj;

var queryNewCustomer = TableOperation.InsertOrMerge(_dQuery1);
TableResult _result = await customerTable.ExecuteAsync(queryNewCustomer);

Now to read back the property details there is a method called Customer _gCus = EntityPropertyConverter.ConvertBack<Customer>(_c.Properties, opc);

The method will return the object we saved, in this case, a customer object, now insider customer we can get the order array property.

var tableClient = storageAccount.CreateCloudTableClient();
var customerTable = tableClient.GetTableReference("codTable");

AzureTable.TableQuery<DynamicTableEntity> _query = new AzureTable.TableQuery<DynamicTableEntity>();
var entities = new List<DynamicTableEntity>();

TableContinuationToken token = null;

do {
var _queryResult = await customerTable.ExecuteQuerySegmentedAsync(new TableQuery<DynamicTableEntity>(), token);
entities.AddRange(_queryResult.Results);
token = _queryResult.ContinuationToken;
}
while (token != null);


CustomerV1 _cust;

foreach (DynamicTableEntity _c in entities)
{                    
var _gCus = ObjectFlattenerRecomposer.Core.EntityPropertyConverter.ConvertBack<CustomerV1>(_c.Properties);
	_cust = new CustomerV1();
	_cust.Firstname = _gCus.Firstname;
	_cust.Lastname = _gCus.Lastname;
	_cust.Mobile = _gCus.Mobile;
	_cust.UpdateDT = _gCus.UpdateDT;
	_cust.Orders = _gCus.Orders;
	_cust.RowKey = _c.RowKey;
	_cust.PartitionKey = _c.PartitionKey;
	customerList.Add(_cust);
}

Notice, while converting back the property of custom type, the rowkey and partition key become irrelevant, not even for the array properties (Orders), everything comes under the row key and partition key of DynamicTableEntity object, all properties falls under that, considered as one object. When we delete the DynamicTableEntity with that rk and pk, all objects under that, will be deleted.

Wait! there is some issue Flatten of Cosmos Table reference, Flatten method not working var _fCustomer = EntityPropertyConverter.Flatten(_customer, epop, opc);. i will update this part again after trying with different version.

 
Azure Cloud Tutorial
learn azure cloud development

Let's learn how to use Azure Cloud Storage system from Ap.net core c# application.

Data Analysis
learn Artificial Intelligence
Cloud Table parent child entity
Learn Azure Cloud Development