Cosmos DB对数据库的分区访问 [英] Cosmos DB partitioned access to a database

查看:89
本文介绍了Cosmos DB对数据库的分区访问的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用cosmosDB实现多租户应用程序.我正在使用分区键来分隔多个用户数据.按照最佳做法,我试图允许每个租户拥有自己的数据库访问令牌.

I am implementing a multi-tenant application using cosmosDB. I am using partition keys to separate multiple users data. Following best practices i am trying to allow each tenant to have its own db access token.

我创建一个用户和权限,并使用创建的令牌访问该分区.但是我收到以下错误:

I create a user and permission and use the created token to access the partition. But I get the following error:

提供的分区键与集合中的定义不对应或与指定的分区键字段值不匹配 在文档中. ActivityId:1659037a-118a-4a2d-8615-bb807b717fa7,Microsoft.Azure.Documents.Common/1.22.0.0,Windows/10.0.17134 documentdb-netcore-sdk/1.9.1

Partition key provided either doesn't correspond to definition in the collection or doesn't match partition key field values specified in the document. ActivityId: 1659037a-118a-4a2d-8615-bb807b717fa7, Microsoft.Azure.Documents.Common/1.22.0.0, Windows/10.0.17134 documentdb-netcore-sdk/1.9.1

我的代码如下:

构造函数启动客户端

public Projects (CosmosDbConfig cosmosConfig)
{
    config = cosmosConfig;
    client = new DocumentClient(new Uri(config.Endpoint), config.AuthKey);
    collectionUri = UriFactory.CreateDocumentCollectionUri(config.Database, config.Collection);
    config.AuthKey = GetUserToken().Result;;
    client = new DocumentClient(new Uri(config.Endpoint), config.AuthKey);
}

get user函数创建用户并检索令牌.用户ID是分区键.

The get user function creates the user and retrieves the token. User Ids are partition keys.

private async Task<string> GetUserToken()
{
        User user = null;
        try
        {
            try
            {
                user = await client.ReadUserAsync(UriFactory.CreateUserUri(config.Database, config.PartitionKey));

            var permission = await GetorCreatePermission(user, config.Collection, config.PartitionKey);
            return permission.Token;
        }
        catch (Exception ex) {
            Console.WriteLine(ex.Message);
        }
        if (user == null)
        {
            user = new User
            {
                Id = config.PartitionKey
            };
            user = await client.CreateUserAsync(UriFactory.CreateDatabaseUri(config.Database), user);
            var permission = await GetorCreatePermission(user, config.Collection, config.PartitionKey);
            return permission.Token;
        }
        else
        {
            throw new Exception("");
        }
    }
    catch (Exception ex)
    {
        throw ex;
    }
}

每个集合都具有权限,因为ID对于每个用户都是唯一的,所以集合名称保留为ID.

Permission are done per collections and holds the collection name as ID since Ids are unique per user.

    private async Task<Permission> GetorCreatePermission(User user,
         string collection,
         string paritionKey)
    {
        var permDefinition = new Permission
        {
            Id = collection,
            PermissionMode = PermissionMode.All,
            ResourceLink = collectionUri.OriginalString,
            ResourcePartitionKey = new PartitionKey(paritionKey),
        };
        var perms = client.CreatePermissionQuery(user.PermissionsLink).AsEnumerable().ToList();
        var perm = perms.FirstOrDefault(x => x.Id == collection);
        if (perm != null)
        {
            return perm;
        }
        else
        {
            var result = await client.CreatePermissionAsync(user.SelfLink, permDefinition);
            perm = result.Resource;
            return perm;
        }

    }

create函数利用新的客户端,并在发生错误的地方使用该客户端.

The create function utilizes the new client and this where the error occurs.

    public async Task<string> Create(Project p)
    {
        var result = await client.CreateDocumentAsync(collectionUri, p, new RequestOptions()
        { PartitionKey = new PartitionKey(config.PartitionKey),
        });
        var document = result.Resource;
        return document.Id;
    }

推荐答案

由于错误提示分区键不正确,我建议您在创建集合时尝试定义分区键路径:

Since error says that partition key is incorrect i can suggest you try define partition key pathes while creating collection:

var docCollection = new DocumentCollection();
docCollection.Id = config.CollectionName;   
docCollection.PartitionKey.Paths.Add(string.Format("/{0}", config.PartitionKey );
collectionUri = UriFactory.CreateDocumentCollectionUri(config.Database, docCollection);

这篇关于Cosmos DB对数据库的分区访问的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆