C# DynamoDB 复杂类型 IList<T> 转换器

标签 c# list amazon-web-services converter amazon-dynamodb

我需要添加一个 IList<MyCustomType>作为DynamoDBProperty进入一个 DynamoDB 表,其项目由类 MyTableItem 定义.

使用此 AWS Documentation page 中的信息, 我为 MyCustomType 实现了转换器(不适用于 IList<MyCustomType> )。 但是在创建新的 MyTableItem 时我注意到 ToEntry()方法接收类型为 IList<MyCustomType> 的对象作为参数而不是 MyCustomType .

阅读文档后我了解到列表(ListIList,或一般的集合)由 DynamoDB 自动处理...

我怎样才能达到预期的效果?

这是代码:

// MyTableItem
[Serializable]
public class MyTableItem
{
    [DynamoDBHashKey]
    public string Id { get; set; }

    [DynamoDBProperty]
    public string Field1 { get; set; }

    [DynamoDBProperty]
    public string Field2 { get; set; }

    // List of MyCustomType objects
    [DynamoDBProperty(typeof(MyCustomTypeConverter))]
    public IList<MyCustomType> CustomField { get; set; }
}

// MyCustomType
[Serializable]
public class MyCustomType
{
    public string DocumentType { get; set; }
    public string Status { get; set; }
    public string Code { get; set; }
}

// Converter methods
public class MyCustomTypeConverter : IPropertyConverter
{
    public DynamoDBEntry ToEntry(object value)
    {
        if (value == null)
            return new Primitive { Value = null };

        MyCustomType item = value as MyCustomType;
        if (item == null)
            throw new InvalidCastException("Cannot convert MyCustomType to DynamoDBEntry.");

        string data = string.Format("{0};{1};{2}", item.DocumentType, item.Status, item.Code);

        DynamoDBEntry entry = new Primitive { Value = data };

        return entry;
    }

    public object FromEntry(DynamoDBEntry entry)
    {
        if (entry == null)
            return new MyCustomType();

        Primitive primitive = entry as Primitive;
        if (primitive == null || !(primitive.Value is string) || string.IsNullOrEmpty((string)primitive.Value))
            throw new InvalidCastException("Cannot convert DynamoDBEntry to MyCustomType.");

        string[] data = ((string)(primitive.Value)).Split(new string[] { ";" }, StringSplitOptions.None);
        if (data.Length != 3)
            throw new ArgumentOutOfRangeException("Invalid arguments number.");

        MyCustomType complexData = new MyCustomType
        {
            DocumentType = Convert.ToString(data[0]),
            Status = Convert.ToString(data[1]),
            Code = Convert.ToString(data[2])
        };

        return complexData;
    }
}

最佳答案

看来DynamoDb SDK序列化没有问题IList<T> ,它在反序列化方面确实存在问题。只是猜测,但这可能是因为它不知道要使用哪种具体类型。

我的设置与您的类似,我尝试更改我的文档以使用 List<T>并且 SDK 能够在不添加任何自定义的情况下进行反序列化 IPropertyConverter实现。

看起来完整的双向支持只有在公开具体列表而不是接口(interface)时才会存在。所以这是解决问题的一种可能方法。

但是如果你想尝试解决IList的问题我会处理 SDK 实际发送给您的 IList ,而不是列表中的项目。对我来说,遍历该列表并将每个项目转换为条目列表是有意义的。对于反序列化,您将取回该条目集合,并且您可以构建一个新的模型列表。

TL;DR 如果可以的话使用一个列表,否则根据 IList<T> 实现你的转换器不是T .

关于C# DynamoDB 复杂类型 IList<T> 转换器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39293249/

相关文章:

amazon-web-services - 如何在 Redshift 中生成 12 位唯一数字?

c# - 使用 Left Join 转换 LINQ 内部联接

javascript - 当面板ID动态生成时,点击时如何获取面板的ID

node.js - 我正在尝试从 DynamoDB 表获取各个属性,并在回调之前将它们转换为变量

python - 在给定范围内查找列表的所有可能子列表的高效和 Pythonic 方法,以及将其中的所有元素相乘后的最小乘积?

Scala 如何使用模式匹配与非通用 LazyList?

node.js - 用于将文件从 s3 复制到 s3 存储桶的 Node js 代码

c# - 用于搜索日期的 SQL 查询

c# - FileSystemWatcher 中的 FileNotFoundException

列表 - 计算与其上一项相关的原子