Hi, thanks for the question. Arwind is correct, and the behavoir you are seeing is "normal" - arrays will not be stored in table entities, as they are not one of the types supported by .NET Data Services (bool, DateTime, Byte[], byte[], double, Guid, int,
Int32, Int64, and string). However, you can store a non-supported type (including your double[]) by converting to and from one of the supported types, likely either string or one of the byte arrays. Here's some sample code that shows storing an array of doubles
as a semicolon delimited string, but you could obviously change it to a different format or use this approach to deal with storing other types as well. Please make sure you test it for your uses, as this is just "proof-of-concept" type code, not tested for
production uses (though I've at least tried to include suggestions for null and empty cases). One note to keep in mind with this code and others, is that the maximum legal size for a table entity is 1MB, and the maximum size for a batch transaction is 4MB.
So if your serialization format is large (like XML), then you may run into those limits earlier.
Some brief explanation of this code: your application would do all access through the get/set for MyDoubles. When you set MyDoubles, this will set myDoubles and also set myDoubleString. Operations to and from table storage will then use the get/set for MyDoubleString.
The “get” reads myDoubleString, which is always updated by the set for MyDoubles, and the “set” (used when reading entities from table storage), initializes myDoubles appropriately.
// A simple enitity which has a double array
public class DoublesArrayEntity : TableServiceEntity
{
private double[] myDoubles;
private string myDoubleString;
// This is for access by your application, which will work with the array.
public double[] MyDoubles
{
get
{
// Just return the private array, which is updated by both setters
return myDoubles;
}
set
{
// Simple assignment to the private array
myDoubles = value;
// This check is necessary to make sure we preserve "null" as different than "empty"
if (myDoubles != null)
{
// Build a string representing the doubles in the list, like "1.5;2.2;3.4;4.8"
StringBuilder sb = new StringBuilder();
foreach (double d in value)
{
sb.Append(d);
sb.Append(';');
}
// Trim the last semi-colon, so that we have "1;2;3" instead of "1;2;3;"
myDoubleString = sb.ToString().TrimEnd(';');
}
else
{
// Assign null to the string to preserve the fact that the array was null
myDoubleString = null;
}
}
}
// This is for storing in table storage
public string MyDoubleString
{
get
{
// Just return the private string, which is updated by both setters
return myDoubleString;
}
set
{
// Simple assignment of the string read from table storage
myDoubleString = value;
// Initialize the array by converting the string. Make sure that null and empty are treated correctly.
if (!String.IsNullOrEmpty(myDoubleString))
{
// Split on ';' to get the individual doubles
string[] dStrings = value.Split(';');
int len = dStrings.Length;
// Create an array the same length
myDoubles = new double[len];
for (int i = 0; i < len; i++)
{
// Store each in the same order they were retured.
myDoubles[i] = Convert.ToDouble(dStrings[i]);
}
}
// Empty string would split to one string if we didn't handle it separately, resulting in the wrong array.
else if (myDoubleString == String.Empty)
{
// So we just create a new empty array here.
myDoubles = new double[0];
}
else
{
// If it's null, just assign that.
myDoubles = null;
}
}
}
public DoublesArrayEntity() { }
}
-Jeff