Azure表存储:“参数计数不匹配”存储数组/列表/ IEnumerable

问题描述 投票:0回答:2

我正在尝试编写一个包含集合的简单对象,例如:

public class UserModel
{
    public string FirstName { get; set; }
    public List<string> GroupIDs { get; set; }
}

使用DynamicTableEntityFlatten方法,我在提交实体之前设置属性,方法是将UserModel对象作为userModel传递,如下所示:

var entity = new DynamicTableEntity(partitionKey, rowKey);
entity.Properties = TableEntity.Flatten(userModel, new OperationContext());

这不可避免地会返回上述错误:

参数计数不匹配

据我所知,这是由于here描述的'flatten'方法。我已经尝试将我的GroupIDs对象设置为数组,List和IEnumerable而没有运气(同样的问题)。

有没有人建议使用Azure表存储中此类对象的flatten方法使用字符串集合提交此对象?

c# azure azure-table-storage
2个回答
2
投票

我想分享我是如何解决这个问题的,因为使用DynamicTableEntity并不是很清楚;至少我能轻易找到。如果还有其他建议我很乐意取消这个答案。

选项1:连接

根据您的要求,如果连接结果超过64KB限制,这将是一个不好的选择。我确定还有其他方法,但以下方法是一个适合我的选项。首先,我更改了模型以反映字符串而不是字符串列表:

public List<string> GroupIDs { get; set; } //instead of this

public string GroupIDs { get; set; } //to this

我将我的列表转换如下:

var groupList = new List<string>{ "123", "456", "789" };
var userObject = new UserModel(
{
    FirstName = "Jason";
    GroupIDs = string.Join(",", groupList);
});

现在userObject.GroupIDs属性是一个字符串,可以像我在原始帖子中显示的那样编写。

选项2:表格设计修改

我最终选择了第二条路线,因为通过引用原始对象上的ID更容易存储和重新水合对象。我不得不修改UserModel以删除对组的任何引用,然后我需要添加一个唯一的ID,如下所示:

public class UserModel
{
    public string FirstName { get; set; }
    public string UserId { get; set; }
}

我为原始表引用的组创建了一个表。我开始创建一个GroupModel对象来保存我需要引用的UserId

public class GroupModel
{
    public string UserId { get; set; }
    public string GroupId { get; set; }
    public string GroupName { get; set; }
}

然后我写了一个新方法来分别处理每个对象,如下所示:

public Interface ITableOps
{
    Task WriteNewUser(UserModel user, List<GroupModel> groups);
}

public class TableOps : ITableOps
{
    public async Task WriteNewUser(UserModel user, List<GroupModel>, groups)
    {
        //...assume user table connection is created

        var entity = new DynamicTableEntity(partitionKey, rowKey);
        entity.Properties = TableEntity.Flatten(user, new OperationContext());
        await userTable.ExecuteAsync(TableOperation.Insert(user));

        //...assume group table connection is created

        groups.ForEach(async g =>
            {
                var groupsEntity = new DynamicTableEntity(user.UserId, Guid.NewGuid().ToString());
                groupsEntity.Properties = TableEntity.Flatten(g, new OperationContext());
                await groupsTable.ExecuteAsync(TableOperation.Insert(groupsEntity));
            });
    }

最后,我编写了一个简单的方法来从Groups表中读取Groups的整个分区。


0
投票

是的SDK中的TableEntity.Flatten不支持ICollection/IEnumerable类型属性。但是ObjectFlattener API的v2.0在这里支持IEnumerable / ICollection等propoerties。 https://www.nuget.org/packages/ObjectFlattenerRecomposer/

我在Nuget包描述中添加了一些用法示例,它与使用TableEntity.Flatten/ConvertBack api非常相似,但支持所有属性类型。

© www.soinside.com 2019 - 2024. All rights reserved.