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

时间:2016-09-02 13:08:38

标签: 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;
    }
}

1 个答案:

答案 0 :(得分:3)

似乎DynamoDb SDK没有问题序列化 IList<T>,它确实无法反序列化。只是推测,但这可能是因为它不知道使用哪种具体类型。

我有类似的设置,我尝试更改文档以使用List<T>,SDK可以反序列化而无需添加任何自定义IPropertyConverter实现。

如果您公开具体的List而不是接口,那么看起来只有完整的双向支持。这是摆脱问题的一种可能方式。

但是如果你想尝试解决IList我将使用SDK实际发送给你的内容的问题,IList,而不是列表中的项目。对我来说,迭代该列表并将每个项目转换为条目列表是有意义的。对于反序列化,您将获得该条目集合,并且您可以建立新的模型列表。

TL; DR如果可以,请使用列表,否则针对IList<T>而不是T实施转换。