You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Azure.Data.Tables .NET SDK保存Dictionary触发NotSupportedException问题

Azure.Data.Tables 保存含Dictionary属性实体报错解决方案

报错原因

Azure Table Storage 以及 Cosmos DB Table API 底层仅支持EDM标准定义的基础数据类型(字符串、布尔、数值、GUID、DateTime、二进制等),不支持直接存储Dictionary这类集合复杂类型。
你之前使用Cosmos DB SQL API可以正常保存,是因为SQL API原生支持完整JSON结构的复杂类型存储,和Azure.Data.Tables库的序列化限制无关,也和System.Text.Json本身是否支持Dictionary序列化无关,是Table类存储的类型限制导致的报错。

可用解决方案

方案一:字典转JSON字符串存储(最简便)

新增字符串属性做中转,字典属性标记为忽略序列化,读写时自动做序列化/反序列化转换,代码示例如下:

using System.Runtime.Serialization;
using System.Text.Json;

class PersistedPerson : ITableEntity
{
    // ITableEntity 必要属性
    public string PartitionKey { get; set; }
    public string RowKey { get; set; }
    public DateTimeOffset? Timestamp { get; set; }
    public ETag ETag { get; set; }

    public string Name { get; init; }
    
    [IgnoreDataMember]
    public Dictionary<Guid, Guid> SomeDictionary { get; init; } = new();

    // 实际落库属性
    public string SomeDictionaryStorage
    {
        get => JsonSerializer.Serialize(SomeDictionary);
        set => SomeDictionary = string.IsNullOrWhiteSpace(value) ? new() : JsonSerializer.Deserialize<Dictionary<Guid, Guid>>(value);
    }
}

方案二:自定义实体序列化逻辑

如果存在多个复杂类型属性,可以实现ITableEntity的读写方法统一控制序列化规则,示例如下:

using Microsoft.Azure.Cosmos.Table;
using System.Text.Json;

class PersistedPerson : ITableEntity
{
    public string PartitionKey { get; set; }
    public string RowKey { get; set; }
    public DateTimeOffset? Timestamp { get; set; }
    public ETag ETag { get; set; }

    public string Name { get; init; }
    public Dictionary<Guid, Guid> SomeDictionary { get; init; } = new();

    public void WriteEntity(IDictionary<string, object> properties, OperationContext operationContext)
    {
        properties.Add(nameof(Name), Name);
        properties.Add(nameof(SomeDictionary), JsonSerializer.Serialize(SomeDictionary));
    }

    public void ReadEntity(IDictionary<string, object> properties, OperationContext operationContext)
    {
        Name = properties.TryGetValue(nameof(Name), out var nameVal) ? nameVal as string : default;
        if (properties.TryGetValue(nameof(SomeDictionary), out var dictVal) && dictVal is string dictJson)
        {
            SomeDictionary = JsonSerializer.Deserialize<Dictionary<Guid, Guid>>(dictJson) ?? new();
        }
    }
}

方案三:切换存储服务

如果业务大量依赖复杂JSON结构存储,不想做额外的序列化改造,可以直接使用Cosmos DB SQL API,该场景下无需修改模型即可正常运行。

内容的提问来源于stack exchange,提问作者Jason Shave

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.24 14:36:09