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

时间:2019-04-18 03:23:17

标签: c# azure azure-table-storage

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

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()); 来设置实体的属性,如下所示:

GroupIDs

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

  

参数计数不匹配

据我所知,这是由于here中所述的“扁平化”方法造成的。我尝试将=AND($A2="Core", $B2="Trainee", $C2<=111) 对象设置为数组,列表和IEnumerable,但没有运气(同一问题)。

是否有人对Azure表存储中的这种类型的对象使用flatten方法向该对象提交带有字符串集合的建议?

2 个答案:

答案 0 :(得分: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));
            });
    }

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

答案 1 :(得分:0)

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

我在Nuget软件包说明中放入了一些用法示例,它与使用ICollection/IEnumerable api非常相似,但是支持所有属性类型。