【问题标题】:Azure Table not loading properties into objectAzure Table 未将属性加载到对象中
【发布时间】:2017-07-26 19:22:41
【问题描述】:

我有一个对象Record,它有一个Name 和一个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属性”

【问题讨论】:

    标签: azure asp.net-core azure-table-storage asp.net-core-1.1 azure-tablequery


    【解决方案1】:

    您可能已经知道 Azure Tables 是一个 Key/Value 存储。但是要考虑的要点是 Value 可以是以下预定义类型:StringInt32Int64DateTimeOffsetDoubleGUIDBinary

    在您的情况下,属性 Theme 的值是 Theme 类型,它不是受支持的类型之一,因此存储客户端库不会对其进行反序列化,因此您将获得 null 值。

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

    【讨论】:

    • 我不使用 JSON,因为我已经在表格中有主题,我只需要“01”来标识主题...有没有办法明确地说“取字符串“主题”并使用new Theme(string)创建类“
    • 如果您的主题已经存储在表中,您可以查询该表,然后您可以获得主题对象。不过,您必须向 Table Storage 发出 2 个请求。
    • 我使用查询将我的主题加载到主题列表中。但是记录中没有“主题”属性的问题。
    • 您能否提供一个示例如何提出这 2 个请求,因为我不太清楚如何实现它。
    【解决方案2】:

    我找到了一个“简单”的解决方案,使用string 而不是Theme 作为Theme 属性的类型...

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

    【讨论】:

      【解决方案3】:

      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

      并将展平对象以DynamicTableEntity 的形式插入到 Azure 表存储中。

      一旦你读回来,你就使用TableEntity.ConvertBack&lt;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 类型外,还支持所有其他类型的复杂、简单、类、结构、枚举等属性

      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-table-storage/

      除此之外,如果您想要自定义转换逻辑,即。从字符串 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__

      【讨论】:

      • 所以,你的意思是,假设我有 3 个主题和数千条记录。每条记录都将其主题作为 JSON 存储在表中,而不仅仅是主题键作为字符串?如果明天,说第一个主题更改其文本描述怎么办?保存的记录将具有过时的主题名称?
      • 不,不像 Json。 Flatten 方法会将整个 Record 对象扁平化为扁平结构,因此在您的示例中,记录对象上的复杂 Theme 属性将扁平化为 2 个键值对,对应名称为 Theme_Description 和 Theme_Key。它们的值将是从它们的字符串值创建的 EntityProperties。
      • 好的,这不会改变主题“名称”将被“序列化”的问题......所以如果我的应用程序是多语言的,例如......
      猜你喜欢
      • 1970-01-01
      • 2021-09-19
      • 2015-11-15
      • 2015-06-13
      • 2015-09-21
      • 1970-01-01
      • 1970-01-01
      • 2011-10-03
      • 2022-11-19
      相关资源
      最近更新 更多