TableServiceContext不会序列化ValueObjects

时间:2012-03-01 10:46:01

标签: c# azure azure-storage azure-table-storage

我有以下数据结构:

[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?

感谢。

3 个答案:

答案 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);