我有以下数据结构:
[DataServiceEntity]
public class User
{
public string RowKey { get; set; }
public string PartitionKey { get; set; }
public DateTime Timestamp { get; set; }
public AddressValueObject Address { get; set; }
}
[DataServiceEntity]
public class AddressValueObject
{
public string City { get; set; }
public string Street { get; set; }
}
现在我正在创建User类的新实例,并尝试使用以下方法将其保存到Windows Azure表存储模拟器中:
void CreateAndSaveNewUser()
{
var userInstance = new User
{
RowKey = "SomeRowKey",
PartitionKey = "SomePartitionKey",
Address = new AddressValueObject
{
City = "SomeCity",
Street = "SomeStreet"
}
};
var tableServiceContext = CloudStorageAccount
.DevelopmentStorageAccount
.CreateCloudTableClient()
.GetDataServiceContext();
tableServiceContext.AddObject("UserTable", userInstance);
tableServiceContext.SaveChanges();
}
现在的问题是AddressValueObject未正确序列化。 在存储中只有一个名为AddressValueObject的列是emtpy。
没有创建AddressValueObject_City和AddressValueObject_Street的列。
我做错了什么?我错过了一些属性吗?
Azure Table Storage是否支持引用的ValueObjects?
感谢。
答案 0 :(得分:3)
只是你做不到。表存储是一个简单的表,不支持复杂类型。因此不支持关系或约束。 作为一种解决方法,您可能会考虑存储分区键和存储在另一个表中的相关对象的行键。 如果你想使用关系,那么最好的选择是SQL Azure。
答案 1 :(得分:2)
Fabio Cozzolino是对的。 Microsoft Azure表存储客户端不支持序列化。但是,您可以手动序列化对象并将其存储为XML字符串或byte []。
我编写了一个支持序列化的客户端。我还包括许多其他功能,如数组,枚举和大于64K的数据。您可以在www.lucifure.com上查看,或通过NuGet下载Lucifure Stash。
答案 2 :(得分:0)
我在Nuget中编写了ObjectFlattenerRecomposer API,允许在Azure Table Storage中编写和读取复杂对象。
Nuget包:https://www.nuget.org/packages/ObjectFlattenerRecomposer/
博客:https://doguarslan.wordpress.com/2016/02/03/writing-complex-objects-to-azure-table-storage/
API提供了将复杂对象展平为EntityProperty字典的功能,以及从展平属性字典中重构原始复杂对象的功能。一种用法是API允许将具有嵌套属性的任何复杂对象以平面形式写入Azure表存储,这通常不可能使用Azure存储客户端SDK。
API还允许您将Enum,TimeSpan,DateTimeOffset,Nullable属性类型保存到Azure表存储,这也是Azure存储客户端SDK无法实现的。
用法:
使用ObjectFlattenerRecomposer;
//展平对象并将其转换为EntityProperty Dictionary
Dictionary flattenedProperties = EntityPropertyConverter.Flatten(complexObject);
//创建一个DynamicTableEntity并设置其PK和RK
DynamicTableEntity dynamicTableEntity = new DynamicTableEntity(partitionKey,rowKey);
dynamicTableEntity.Properties = flattenedProperties;
//使用客户端SDK
将DynamicTableEntity写入Azure表存储//使用相同的PK和RK从AzureTableStorage读取实体作为DynamicTableEntity
DynamicTableEntity entity = [使用PK和RK从Azure读取];
//将DynamicTableEntity转换回原始复杂对象。
想象一下原始的complexObject是Order类型。
订单订单= EntityPropertyConverter.ConvertBack(entity.Properties);