.NET Core API:从文档中提取的 PartitionKey 与标头中指定的不匹配

Tom*_*uke 5 c# entity-framework-5 asp.net-core-webapi azure-cosmosdb

背景:

我刚刚开始使用 Azure CosmosDB 并尝试使用实体框架 CosmosDB 提供程序。我创建了一个简单的 API 以及 Swagger API 文档,它将在单个实体上运行。

到目前为止我已经做了以下事情:

  1. 配置新的 Cosmos DB 数据库 + 容器
  2. 将 CosmosDB 注册到 Startup.cs 中的服务容器中
  3. 配置了一个我想要存储在新的 Cosmos DB 容器中的实体
  4. 为基本 CRUD 操作准备 API 端点

问题:

当尝试通过 Swagger 调用我的 POST 端点以在数据库中创建新记录时,出现以下错误:

Microsoft.Azure.Cosmos.CosmosException :响应状态代码不指示成功:BadRequest (400);子状态:1001;活动ID:fe27e816-173c-433e-8699-e9e49e01b96f;原因: (消息: {"Errors":["从文档中提取的 PartitionKey 与标头中指定的不匹配"]}

从以下教程和文档来看,我收到此错误的原因并不明显!任何正确方向的指示将不胜感激!

可能有用的片段可以帮助别人诊断我哪里出了问题:

将 Cosmos DB 注册到服务容器:

var settings = new CosmosDbOptions();

configuration.GetSection(CosmosDbOptions.SECTION_NAME)
    .Bind(settings);

services.AddDbContext<DatabaseContext>(options => 
    {
        options.UseCosmos(
            accountEndpoint: settings.EndpointUri,
            accountKey: settings.PrimaryKey,
            databaseName: settings.DatabaseName
        );
    });
Run Code Online (Sandbox Code Playgroud)

实体:

public class Client : Entity, IGuidIdentifier, IAggregateRoot
{
    public Client() : base() 
    {
        this.Id = Guid.NewGuid();
        this.ClientId = this.Id.ToString();
    }

    public string ClientId { get; private set; }

    public IrisCode IrisCode { get; private set; }

    public string Name { get; private set; }

    public Office Office { get; private set; }

    public Logo Logo { get; private set; }
}
Run Code Online (Sandbox Code Playgroud)

我的实体的实体框架配置:

public class ClientConfig : IEntityTypeConfiguration<Client>
{
    public void Configure(EntityTypeBuilder<Client> builder)
    {
        builder.ToContainer("Clients");
        builder.HasPartitionKey(x => x.ClientId);

        builder.HasKey(x => x.Id);

        builder.Property(x => x.Name);
        builder.Property(x => x.ClientId);
        builder.OwnsOne(x => x.IrisCode);
        builder.OwnsOne(x => x.Office);
        builder.OwnsOne(x => x.Logo);

        builder.Ignore(x => x.DomainEvents);
    }
}
Run Code Online (Sandbox Code Playgroud)

更新:似乎以下行导致了错误,但是,这使我处于没有定义所需分区键的位置。

builder.HasPartitionKey(x => x.ClientId);
Run Code Online (Sandbox Code Playgroud)

Har*_*ngh 2

出现此错误的(PartitionKey extracted from document doesn't match the one specified in the header)原因是您为 Cosmos DB 集合设置的分区键与您在 EF: 中设置的分区键不同ClientId

请确保您的 Collection 具有相同的分区键,例如,您可以使用 C# 设置它,如下所示:

this.Container = await this.Database.CreateContainerIfNotExistsAsync("testContainer", "/clientId");
Run Code Online (Sandbox Code Playgroud)

并将密钥放入您的文档对象中,如下所示:

[JsonProperty(PropertyName = "clientId")]
public string ClientId { get; set; }
Run Code Online (Sandbox Code Playgroud)