【问题标题】:Persisting dynamic object in DynamoDB with .NET SDK使用 .NET SDK 在 DynamoDB 中持久化动态对象
【发布时间】:2017-08-02 13:17:00
【问题描述】:

我正在尝试使用 .NET SDK 将以下类持久化到 DynamoDB:

public class MyClass
{
    public string Id { get; set; }

    public string Name { get; set; }

    public object Settings { get; set; }
}

问题在于设置属性。它可以是任何类型的对象,我事先不知道可能分配给它什么。当我尝试将其持久化到 DynamoDB 时,出现以下异常:

System.InvalidOperationException: 'Type System.Object is unsupported, it has no supported members'

Document Model 和 Object Persistence Model 方法都会导致相同的异常。

有没有办法将这些对象持久保存在 DynamoDB 中? MongoDB 和 Azure DocumentDB 等其他数据库可以毫无问题地执行此操作,并且可以将它们反序列化为带有鉴别器的正确类型,或作为动态 JSON 对象。

【问题讨论】:

  • 先尝试converting Settings to a dictionary,然后尝试将项目持久化到 DynamoDB。
  • 字典可能必须输入IDictionary<string, string>,对吧?
  • 我不敢相信没有解决方案。 DynamoDB 是文档数据库,无法处理?

标签: c# .net asp.net-core amazon-dynamodb


【解决方案1】:

您可以使用此处记录的一般方法:https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBContext.ArbitraryDataMapping.html

这是我对任意对象的实现:

public class DataConverter : IPropertyConverter
{
    public object FromEntry(DynamoDBEntry entry)
    {
        var primitive = entry as Primitive;
        if (primitive == null || !(primitive.Value is String) || string.IsNullOrEmpty((string)primitive.Value))
            throw new ArgumentOutOfRangeException();
        object ret = JsonConvert.DeserializeObject(primitive.Value as string);
        return ret;
    }

    public DynamoDBEntry ToEntry(object value)
    {
        var jsonString = JsonConvert.SerializeObject(value);
        DynamoDBEntry ret = new Primitive(jsonString);
        return ret;
    }
}

然后像这样注释您的属性:

[DynamoDBProperty(typeof(DataConverter))]
public object data { get; set; }

【讨论】:

  • 我将整个对象序列化为表中的字符串而不是映射。不知道我是否做错了
  • 不,这是正确的。 DynamoDB 不支持无限(甚至多级对象深度)。您甚至无法搜索手动构建的地图列表。这个解决方案是在 Dynamo 中存储任意对象。
【解决方案2】:

对上一个答案的小改进:使转换器通用,以便您可以反序列化为正确的类型,如下所示:

public class SerializeConverter<T> : IPropertyConverter
{
    public object FromEntry(DynamoDBEntry entry)
    {
        var primitive = entry as Primitive;
        if (primitive is not { Value: string value } || string.IsNullOrEmpty(value))
            throw new ArgumentException("Data has no value", nameof(entry));
        return JsonConvert.DeserializeObject<T>(value);
    }

    public DynamoDBEntry ToEntry(object value) => 
        new Primitive(JsonConvert.SerializeObject(value));
}

用法:

[DynamoDBProperty(typeof(SerializeConverter<YourType>))]
public YourType data{ get; set; }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-06
    • 2019-04-14
    • 1970-01-01
    • 2016-11-14
    • 1970-01-01
    相关资源
    最近更新 更多