繁体   English   中英

如何将 DynamoDB 属性设置为空列表?

[英]How do I set a DynamoDB attribute to an empty list?

我正在尝试通过更新请求将 DynamoDB 文档中的属性设置为空列表,使用来自 AWS SDK 的 DynamoDBv2 库用于 .NET。

我尝试了明显的更新表达式,但没有成功:

// Fails, expression attribute values cannot contain an empty list
...
ExpressionAttributeValues = new Dictionary<string, AttributeValue> {
    { ":empty", new AttributeValue { L = new List<AttributeValue> { } } },
},
UpdateExpression = "SET #P.MyList = :empty",
...

我怎样才能做到这一点?

我在挖掘 AWS SDK 源代码后找到了答案。 关键是IsLSet属性是可设置的。 这会调用以下代码:

public static void SetIsSet<T>(bool isSet, ref List<T> field)
{
    if (isSet)
        field = new AlwaysSendList<T>(field);
    else
        field = new List<T>();
}

在确定您的 AttributeValue 是否已初始化时,使用以下代码:

public static bool GetIsSet<T>(List<T> field)
{
    if (field == null)
        return false;

    if (field.Count > 0)
        return true;

    var sl = field as AlwaysSendList<T>;
    if (sl != null)
        return true;

    return false;
}

这也说明了为什么使用new AttributeValue { L = new List<AttributeValue> { } }没有预期的效果 - 此方法将返回 false,因为Count为 0。但是,如果检查特殊的AlwaysSendList类型将返回 true您已经设置了IsLSet属性。

回到您的代码,答案是使用以下内容:

...
ExpressionAttributeValues = new Dictionary<string, AttributeValue> {
    { ":empty", new AttributeValue { IsLSet = true } },
},
UpdateExpression = "SET #P.MyList = :empty",
...

对于那些在 Java SDK 中遇到此问题的人,我找到了解决方案。 Java 的库中似乎没有IsLSet类比。 要使用 Java 为 DynamoDB 指定一个空的 AttributeValue 列表,以下工作:

AttributeValue.builder().l(new ArrayList<AttributeValue>()).build();

例如,

String updateExpression = "SET my_list = :empty_list";
Map<String, AttributeValue> expressionAttributeValues = Map.of(
    ":empty_list", AttributeValue.builder().l(new ArrayList<AttributeValue>()).build()
    );

刚刚自己遇到了这个问题。 看起来至少自 2018 年 11 月以来就存在一个错误 ( https://github.com/aws/aws-sdk-net/issues/1116 )。 我的解决方法是在设置L的值后立即手动设置IsLSet = true

例如,以下是创建空列表属性的方法:

ExpressionAttributeValues = new Dictionary<string, AttributeValue> 
{
    { ":empty", new AttributeValue { L = new List<AttributeValue>(), IsLSet = true }},
},
UpdateExpression = "SET #P.MyList = :empty",

无论您的列表是否为空,您都应该能够使用上述语法。 例如:

ExpressionAttributeValues = new Dictionary<string, AttributeValue> 
{
    { ":MyListOfValues", new AttributeValue { L = listValues, IsLSet = true }},
},
UpdateExpression = "SET #P.MyList = :MyListOfValues",

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM