1

我有一个Record具有 aName和 a的对象Theme

Theme 是嵌入在类型化类中的 KeyValue 对,例如“01”-“Sport”、“02”-“Home”等

我有一个这样的对象:

public class DescriptionEntity : TableEntity
{
    public string Description { get; set; }
    public string Key { get { return RowKey; } set { RowKey = value; } }

    public DescriptionEntity() { }
}

public class Theme : DescriptionEntity
{
}

/* The Record has a "string" and a "Theme" property */
public class Record : TableEntity
{
    [...]
    public string Name { get; set; }
    public Theme Theme { get; set; }
}

问题是当我尝试从 Azure 表中加载该记录时,如下所示:

var record = await repository.GetTableEntityAsync<Record>(id, RecordConst.RecordPartitionKey);

// ..........................
public async Task<T> GetTableEntityAsync<T>(string rowKey, string partitionKey) where T : ITableEntity, new()
{
    var table = GetTable<T>();

    TableQuery<T> query = new TableQuery<T>().Where(
        TableQuery.CombineFilters(
           TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, partitionKey),
           TableOperators.And,
           TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, rowKey))).Take(1);

    var result = new T();

    TableContinuationToken continuationToken = null;
    do
    {
        Task<TableQuerySegment<T>> querySegment = table.ExecuteQuerySegmentedAsync(query, continuationToken);
        TableQuerySegment<T> segment = await querySegment;
        result = segment.FirstOrDefault();
        continuationToken = segment.ContinuationToken;
    } while (continuationToken != null);

    return result;
}

我获得了record.Name,但record.Theme仍然始终为“null”,不会从“记录”表中加载,就像:

Partition Key Name    Theme
"record"  "x" "test"  "01"

也在我的“主题”表中

Partition Key  Description
"en"      "01" "Sport"

我试图将构造函数添加到“主题”类

public class Theme : DescriptionEntity
{
    public Theme() : base() { }
    public Theme(string key) : base(key) { }
}

但这并没有改变结果......

有没有办法明确地说“取字符串“主题”并用于new Theme(string)创建Theme属性”

4

3 回答 3

1

您可能已经知道 Azure Tables 是一个Key/Value商店。然而,要考虑的要点是Value可以是以下预定义类型:StringInt32Int64DateTimeOffsetDouble和。GUIDBinary

在您的情况下,属性的值Theme的类型Theme不是受支持的类型之一,因此存储客户端库没有反序列化它,因此您获得了null价值。

一种可能的解决方案是使用 JSON 序列化程序以字符串格式存储此属性的值,并在您获取它时在应用程序中对其进行反序列化。

于 2017-07-24T09:47:13.673 回答
0

Azure 表存储客户端 SDK v8.0.0.0 引入了对具有复杂属性的复杂对象的支持,其中包含 TableEntity 类的 2 个新方法。

要插入复杂对象,请通过以下TableEntity.Flatten方法将其展平: https ://docs.microsoft.com/en-us/dotnet/api/microsoft.windowsazure.storage.table.tableentity.flatten?view=azurestorage-8.1.3

并将扁平对象插入到 azure 表存储中作为DynamicTableEntity.

一旦你读回来,你使用TableEntity.ConvertBack<TypeOfYourComplexObject>

https://docs.microsoft.com/en-us/dotnet/api/microsoft.windowsazure.storage.table.tableentity.convertback?view=azurestorage-8.1.3#Microsoft_WindowsAzure_Storage_Table_TableEntity_ConvertBack__1_System_Collections_Generic_IDictionary_System_String_Microsoft_WindowsAzure_Storage_Table_EntityProperty__Microsoft_WindowsAzure_Storage_OperationContext_

将展平的实体转换为其原始的复杂形式。除了 Collection 和 IEnumerable 类型之外,还支持所有其他类型的属性 complex、simple、class、struct、enum 等

Flatten 方法会将您的整个 Record 对象扁平化为扁平结构,因此在您的示例中,记录对象上的复杂 Theme 属性将扁平化为 2 个键值对,对应名称为 Theme_Description 和 Theme_Key。它们的值将是从它们的字符串值创建的 EntityProperties。因此,一旦将记录对象写入表存储,您就可以单独访问(读取、项目、更新)该记录实体上的 Theme_Description 或 Theme_Key 属性。

您还可以查看我写的关于将复杂的多层次对象写入 azure 表存储的文章:https ://doguarslan.wordpress.com/2016/02/03/writing-complex-objects-to-azure-表存储/

除此之外,如果您想要自定义转换逻辑,即。从字符串 Key 属性到完整的 Theme 属性 我建议您查看Retrieve方法的重载版本,您可以在其中指定自定义 EntityProperty 转换器。 https://docs.microsoft.com/en-us/dotnet/api/microsoft.windowsazure.storage.table.tableoperation.retrieve?view=azurestorage-8.1.3#Microsoft_WindowsAzure_Storage_Table_TableOperation_Retrieve__1_System_String_System_String_Microsoft_WindowsAzure_Storage_Table_EntityResolver___0__System_Collections_Generic_List_System_String__

于 2017-07-25T20:17:50.903 回答
0

我找到了一个“简单”的解决方案来string代替属性Theme类型Theme......

但我想知道是否有一些方法可以自定义控制从表到对象的序列化/加载...

于 2017-07-24T10:07:22.850 回答