使用.NET SDK将动态对象持久化到DynamoDB

12

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

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

    public string Name { get; set; }

    public object Settings { get; set; }
}

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

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

文档模型和对象持久化模型方法都会导致相同的异常。

是否有办法将这些对象持久化到DynamoDB中?其他数据库如MongoDB和Azure DocumentDB可以轻松实现此功能,它们可以反序列化为具有鉴别器的正确类型,或作为动态JSON对象。


首先尝试将“设置”转换为字典,然后尝试将项目持久化到DynamoDB。参考链接 - Alexander Patrikalakis
字典可能需要键值对类型为 IDictionary<string, string>,是吗? - Jonn
2
我简直不能相信这个问题没有解决方案。DynamoDB是一个文档数据库,难道处理不了吗? - JohnOpincar
3个回答

12
你可以使用此处记录的一般方法: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; }

我在表格中得到了整个对象序列化为字符串,而不是映射。不确定我是否做错了。 - LLL
1
不,那是正确的。 DynamoDB 不支持无限(甚至多级)对象深度。 你甚至不能手动搜索一个由地图列表构建的列表。 这个解决方案是将任意对象存储在 Dynamo 中。 - JohnOpincar

1

对之前答案的一点改进:使转换器通用,这样你就可以反序列化到正确的类型,像这样:

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; }

0

我曾经苦苦寻找与非常不规则的数据进行交互的好方法,最终意识到 DynamoDBContext 真的不是为此而设计的。

对于其他人来说,我的建议是降低抽象级别,直接使用 AmazonDynamoDBClientDictionary<string, AttributeValue> 对象。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接