代码之家  ›  专栏  ›  技术社区  ›  Walid Hanafy

数据库的分区访问

  •  0
  • Walid Hanafy  · 技术社区  · 8 年前

    我正在使用cosmosdb实现一个多租户应用程序。我使用分区键来分隔多个用户数据。遵循最佳实践,我试图允许每个租户拥有自己的数据库访问令牌。

    我创建一个用户和权限,并使用创建的令牌访问分区。但我得到了以下错误:

    提供的分区密钥与集合中的定义不一致,或者与指定的分区密钥字段值不匹配。 在文件中。 活动ID:1659037A-118A-4A2D-8615-BB807B717FA7,Microsoft.azure.documents.common/1.22.0.0,Windows/10.0.17134 磊科

    我的代码如下:

    构造函数启动客户端

    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是分区键。

    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都是唯一的。

        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;
            }
    
        }
    

    创建函数使用新的客户机,这个地方发生错误。

        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;
        }
    
    1 回复  |  直到 8 年前
        1
  •  1
  •   Olha Shumeliuk    8 年前

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

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