11

我正在考虑将整个复杂对象添加到表中。由于来自良好的老式 SQL 方法,我显然会将其分成表,但我正在尝试一种不同的方法。所以基本上我有一个对象,它由一个嵌套类(当你反序列化一个 json 集合时得到的一种东西)组成,它具有通常的客户、业务和 InvoiceItems 列表。

public class Business
{
    public string _id { get; set; }
    public string name { get; set; }
    public string street_1 { get; set; }
    public string street_2 { get; set; }
    public string town { get; set; }
    public string county { get; set; }
    public string postcode { get; set; }

 //other fields as needed
}

public class Customer
{
    public string _id { get; set; }
    public string name { get; set; }
    public string street_1 { get; set; }
    public string street_2 { get; set; }
    public string town { get; set; }
    public string county { get; set; }
    public string postcode { get; set; }

    //other fields as needed
 }

public class InvoiceItems
{
    public string item_id { get; set; }
    public string price_per_unit { get; set; }
    public string quanity { get; set; }
    public string date { get; set; }
}

public class WholeObject
{

    public Customer customer { get; set; }
    public Business address { get; set; }
    public List<InvoiceItems> items { get; set; }
}

(样本类真的)

除了 1MB 大小之外,是否有任何限制将其插入表中?我已经阅读了 TableServiceEntity,它应该映射 C# 对象,但它会处理吗?在这个阶段,这是一个非常假设的问题,因为我实际上并没有尝试对其进行编码。任何帮助,将不胜感激。

4

2 回答 2

19

复杂属性不会保存到表存储中。只能保留标准数据类型的子集。查看此链接以获取有关支持哪些数据类型的更多信息:https ://docs.microsoft.com/rest/api/storageservices/Understanding-the-Table-Service-Data-Model#property-types

但是,您想做的事情是可能的,只是实施起来有点困难。这里有两种方法可以做到这一点:

  • 在 WholeObject 类上公开 CustomerSerialized、AddressSerialized 和 ItemsSerialized 属性。让这些属性将其关联的复杂对象序列化/反序列化为字节数组、json 或 xml。这种方法有两个缺点:a)即使您只需要 Customer 对象,您也将始终从 azure 表存储中加载完整的对象树;b)每个对象的每个属性限制为 64kb,因此最好确保 InvoiceItems 集合可以适合 64kb 序列化

  • 提出一个 PartitionKey/RowKey 模式,它允许您将所有类型的相关对象保存为单独的实体,但 PartitionKey/Rowkey 指示它们的关系。这将允许您独立地获取完整的对象树或各个子对象。这种方法没有第一种方法的两个缺点,但在实施时它绝对是复杂的一面。它还限制了您根据其他业务需求调整 PartitionKey/RowKey 的能力。我已经为一家大型电子商务公司使用了这种方法,并取得了很大的成功。

在我的项目中,所有实体(根和子)的 PartitionKey 都映射到“WholeObject”的 ID,而 RowKey 由 ParentObjectID、ChildObjectID 和 ChildObjectType 的串联组合组成。当需要检索 WHoleObject 中的所有对象时,只需对 PartitionKey 发出查询,否则使用 PartitionKey 和部分 RowKey 来获取某些类型的对象(即:所有地址)或 PartitionKey 和完整 RowKey 来获取个人实体。这种方法支持无限深的对象树结构,但是,一旦实体数量超过 100,将对象存储在一个事务中就令人头疼。

于 2013-11-10T02:46:59.357 回答
16

我遇到了类似的问题,并实现了一个通用的对象扁平化器/重构器 API,它将你的复杂实体扁平化为扁平EntityProperty字典,并使它们可写入表存储,以DynamicTableEntity.

EntityProperty然后,相同的API将从DynamicTableEntity.

看看:https ://www.nuget.org/packages/ObjectFlatenerRecomposer/

用法:

//Flatten object of type Order) and convert it to EntityProperty Dictionary
 Dictionary<string, EntityProperty> flattenedProperties = EntityPropertyConverter.Flatten(order);

// Create a DynamicTableEntity and set its PK and RK
DynamicTableEntity dynamicTableEntity = new DynamicTableEntity(partitionKey, rowKey);
dynamicTableEntity.Properties = flattenedProperties;

// Write the DynamicTableEntity to Azure Table Storage using client SDK

//Read the entity back from AzureTableStorage as DynamicTableEntity using the same PK and RK
DynamicTableEntity entity = [Read from Azure using the PK and RK];

//Convert the DynamicTableEntity back to original complex object.
 Order order = EntityPropertyConverter.ConvertBack<Order>(entity.Properties);

从那时起,我与 azure 团队合作,并将此功能集成到 Azure Storage SDK 8.0 版。

重要的一点是 Azure SDK 中的 api 不支持IEnumerableICollection键入属性。但是,如果您在上述链接中获得了 nuget 包 v2,您几乎可以将任何对象写入 Azure 表存储,包括具有可枚举、集合类型属性的对象。

https://msdn.microsoft.com/en-us/library/microsoft.windowsazure.storage.table.tableentity.flatten.aspx

https://msdn.microsoft.com/en-us/library/azure/mt775432.aspx

我还在TableEntityAdapterSDK 版本 8.2.0 中添加了类,以使使用更容易。只需将您的复杂实体传递给其构造函数,它将透明地处理在写入和读取时展平/转换回您的复杂对象。 https://github.com/Azure/azure-storage-net/blob/master/Lib/Common/Table/TableEntityAdapter.cs

于 2016-03-11T14:19:26.840 回答