Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Storing decimal data type in Azure Tables

Windows Azure Table Storage does not support the decimal data type.

A suggested workaround is to use a custom attribute to serialize the decimal property as string:

[EntityDataType(PrimitiveTypeKind.String)]
public decimal Quantity { get; set; }

How could this EntityDataType custom attribute be implemented so decimal properties can be stored and retrieved from Windows Azure Tables?

like image 586
Fernando Correia Avatar asked Jun 17 '12 14:06

Fernando Correia


People also ask

What type of data does Azure table storage store?

Azure Table storage is a service that stores non-relational structured data (also known as structured NoSQL data) in the cloud, providing a key/attribute store with a schemaless design. Because Table storage is schemaless, it's easy to adapt your data as the needs of your application evolve.

Does Azure table storage supports multiple write regions?

Azure Table Storage supports a single region with an optional read-only secondary region for availability. Cosmos DB supports distribution from 1 to more than 30 regions with automatic failovers worldwide.

What are the key elements of Azure table storage?

The key in an Azure Table Storage table comprises two elements. The partition key that identifies the partition containing the row, and a row key that is unique to each row in the same partition. Items in the same partition are stored in row key order.

What is azure Datatable?

Azure Tables is a NoSQL data storage service that can be accessed from anywhere in the world via authenticated calls using HTTP or HTTPS. Tables scales as needed to support the amount of data inserted, and allow for the storing of data with non-complex accessing.


1 Answers

Overriding ReadEntity and WriteEntity in the base class is good for this. It's not necessary to write an EntityResolver every time you retrieve the entities.

public class CustomTableEntity : TableEntity
{
    public override void ReadEntity(IDictionary<string, EntityProperty> properties, OperationContext operationContext)
    {
        base.ReadEntity(properties, operationContext);

        foreach (var thisProperty in
            GetType().GetProperties().Where(thisProperty =>
                thisProperty.GetType() != typeof(string) &&
                properties.ContainsKey(thisProperty.Name) &&
                properties[thisProperty.Name].PropertyType == EdmType.String))
        {
            var parse = thisProperty.PropertyType.GetMethods().SingleOrDefault(m =>
                m.Name == "Parse" &&
                m.GetParameters().Length == 1 &&
                m.GetParameters()[0].ParameterType == typeof(string));

            var value = parse != null ?
                parse.Invoke(thisProperty, new object[] { properties[thisProperty.Name].StringValue }) :
                Convert.ChangeType(properties[thisProperty.Name].PropertyAsObject, thisProperty.PropertyType);

            thisProperty.SetValue(this, value);
        }
    }

    public override IDictionary<string, EntityProperty> WriteEntity(OperationContext operationContext)
    {
        var properties = base.WriteEntity(operationContext);

        foreach (var thisProperty in
            GetType().GetProperties().Where(thisProperty =>
                !properties.ContainsKey(thisProperty.Name) &&
                typeof(TableEntity).GetProperties().All(p => p.Name != thisProperty.Name)))
        {
            var value = thisProperty.GetValue(this);
            if (value != null)
            {
                properties.Add(thisProperty.Name, new EntityProperty(value.ToString()));
            }
        }

        return properties;
    }
}

When you use, just make your entities extend from CustomTableEntity and it will be transparent when inserting or retrieving entities. It supports DateTime, TimeSpan, decimal and those types who have Parse method or implement IConvertible interfaces.

like image 66
Liu Yue Avatar answered Sep 28 '22 08:09

Liu Yue