尽管 EF Core 和 Terraform 中的分区键设置匹配,但 CosmosDB PartitionKey 错误

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

我正在使用 EF Core 在 ASP.NET Core 应用程序中使用 CosmosDB。我有一个带有

Slug
属性的 Post 类,我将其用作分区键。但是,我在尝试将 Post 对象保存到 CosmosDB 时遇到错误。

这是Post课程:

public partial class Post 
{
    public string Id { get; set; }

    [Key]
    public string Slug { get; set; }

    [Required]
    [MaxLength(100)]
    public string Title { get; set; }

    [Required]
    [MaxLength(100)]
    public string Subtitle { get; set; }

    public string Markdown { get; set; }

    [Required]
    [MaxLength(50)]
    public string Author { get; set; }

    [DataMember(Name = "created_at")]
    [JsonPropertyName("created_at")]
    public DateTime? CreatedAt { get; set; }

    [DataMember(Name = "updated_at")]
    [JsonPropertyName("updated_at")]
    public DateTime? UpdatedAt { get; set; }

}

我使用 Guid.NewGuid().ToString() 生成 Id,然后将对象保存到 CosmosDB:

public async Task<Post> CreatePostAsync(PostInput postInput)
{
    PostInputValidator.CheckPostInputRequiredFields(postInput);

    Post post = new()
    {
      Id = Guid.NewGuid().ToString(),
      Slug = Guid.NewGuid().ToString() + "-" + postInput.Title.ToLower().Replace(" ", "-") + "-" +   postInput.Author.ToLower(),
      Title = postInput.Title,
      Subtitle = postInput.Subtitle,
      Author = postInput.Author,
      Markdown = postInput.Markdown,
      CreatedAt = DateTime.UtcNow
    };

    _context.Posts.Add(post);
    await _context.SaveChangesAsync();
    return post;
}

但是,我收到以下错误:

{"Errors":["PartitionKey extracted from document doesn't match the one specified in the header. Learn more: https://aka.ms/CosmosDB/sql/errors/wrong-pk-value"]}

这是我的 DbContext:

public class BlogContext : DbContext, IBlogContext
{
    public BlogContext(DbContextOptions<BlogContext> options)
        : base(options)
    {
    }

    public DbSet<Post> Posts { get; set; }

    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Post>().ToContainer("Posts"); 
        modelBuilder.Entity<Post>().HasPartitionKey(p => p.Slug);
        modelBuilder.Entity<Post>().HasNoDiscriminator();
    }
}

这是我的 Terraform CosmosDB 设置:

resource "azurerm_cosmosdb_account" "gt_cosmosdb" {
  name                = "gt-cosmosdb"
  location            = azurerm_resource_group.gt_rg.location
  resource_group_name = azurerm_resource_group.gt_rg.name
  offer_type          = "Standard"
  kind                = "GlobalDocumentDB"
  enable_free_tier    = true
  consistency_policy {
    consistency_level = "Session"
  }
  geo_location {
    location          = azurerm_resource_group.gt_rg.location
    failover_priority = 0
  }
}

resource "azurerm_cosmosdb_sql_database" "gt_database" {
  name                = "gt-db"
  resource_group_name = azurerm_cosmosdb_account.gt_cosmosdb.resource_group_name
  account_name        = azurerm_cosmosdb_account.gt_cosmosdb.name
}

resource "azurerm_cosmosdb_sql_container" "gt_container" {
  name                = "Posts"
  resource_group_name = azurerm_cosmosdb_account.gt_cosmosdb.resource_group_name
  account_name        = azurerm_cosmosdb_account.gt_cosmosdb.name
  database_name       = azurerm_cosmosdb_sql_database.gt_database.name
  partition_key_path  = "/slug"
  throughput          = 400
}

我尝试过的事情:

  1. 在 EF Core 和 CosmosDb 中将分区键设置为 Id。
  2. 生成 ID 作为 GUID 并使用 .ToString()。
  3. 将分区键的类型从 string 更改为 int 并返回。
  4. 改回 /slug 分区键。

尽管如此,错误仍然存在。尽管我已将其配置为在 EF Core 和我的 Terraform 配置中使用 Slug,但分区键似乎不匹配。

问题:

  1. 什么可能导致文档中指定的分区键与标头中的分区键不匹配?
  2. 我生成或设置分区键的方式有问题吗?
  3. Terraform 中分区键的配置方式是否存在问题?

任何帮助或指导将不胜感激!

c# asp.net entity-framework-core terraform azure-cosmosdb
1个回答
0
投票

这只是一个猜测,但我相信分区键区分大小写,并且当前实际分区键属性之间的大小写与您在 Terraform 中指定的大小写不同。

尝试将 Terraform 更改为:

partition_key_path  = "/Slug"

或者更改

Slug
属性的 JSON 名称:

[Key]
[JsonProperty("slug")]
public string Slug { get; set; }
© www.soinside.com 2019 - 2024. All rights reserved.