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?
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With