Ошибка CosmosDB PartitionKey несмотря на совпадение настройки ключа раздела в EF Core и Terraform

Я работаю с CosmosDB в приложении ASP.NET Core, используя EF Core. У меня есть класс Post со свойством Slug, которое я использую в качестве ключа раздела. Однако я столкнулся с ошибкой при попытке сохранить объект 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; }
}

Я генерирую Id, используя Guid.NewGuid().ToString(), а затем сохраняю объект в 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;
}

Однако я получаю следующую ошибку:

PartitionKey, извлеченный из документа, не соответствует тому, который указан в заголовке. Узнайте больше: 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
  2. Создание Id в качестве GUID и использование .ToString()
  3. Изменение типа ключа раздела со string на int и обратно
  4. Возврат к ключу раздела /slug

Несмотря на это, ошибка сохраняется. Похоже, что ключ раздела не совпадает, хотя я настроил его на использование Slug как в EF Core, так и в моей конфигурации Terraform.

Вопросы:

  1. Что может быть причиной несоответствия ключа раздела, указанного в документе, и ключа в заголовке?
  2. Что-то не так с тем, как я генерирую или устанавливаю ключ раздела?
  3. Может ли быть проблема с настройкой ключа раздела в Terraform?

Любая помощь или руководство будут очень признательны!

К вашему сведению, вам нужно будет сопоставить Id с id, поскольку в каждом документе Cosmos DB есть id. и, вероятно, то же самое с вашим ключом раздела (Slug против slug). Да, и вы создаете свою пулю, включая ее собственную направляющую. Не совсем понимаю, почему вы это делаете и разбиваете по пулям, когда у вас уже есть идентификатор в качестве идентификатора (разделение по пулу, который каждый раз уникален, не принесет вам никакой пользы)

David Makogon 15.08.2024 13:53

Кроме того, отредактируйте свой вопрос, чтобы показать примеры данных из вашей коллекции. Сейчас мы можем только догадываться, как это выглядит (и обязательно используйте правильно отформатированный текст, а не скриншот).

David Makogon 15.08.2024 16:33
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
52
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это всего лишь выстрел в темноте, но я считаю, что ключ раздела чувствителен к регистру, и в настоящее время регистр вашего фактического свойства ключа раздела отличается от того, который вы указали в Terraform.

Попробуйте изменить Terraform на:

partition_key_path  = "/Slug"

Или измените JSON-имя вашего свойства Slug:

[Key]
[JsonProperty("slug")]
public string Slug { get; set; }

Какой вариант подойдет вам лучше всего.

Привет @Visual Винсент, я попробовал добавить свойство Json точно так, как вы описали, но, к сожалению, по-прежнему получаю ошибку:

Kevin James 15.08.2024 11:49

Можете ли вы вставить образец документа (видя его в веб-интерфейсе портала или эмулятора), чтобы он подтвердил регистр? В документе должно быть указано «slug» в нижнем регистре (потому что в вашем контейнере в качестве пути к ключу раздела указан «/slug»).

Matias Quaranta 15.08.2024 16:23

Из-за этой ошибки нет образцов документов.

Kevin James 15.08.2024 19:54

@KevinJames К сожалению, мой опыт работы с CosmosDB ограничен. Пробовали ли вы также перевести свойство Id в нижний регистр на id, как предложил Дэвид в своем комментарии к вашему вопросу?

Visual Vincent 17.08.2024 09:26

Из-за чувствительности к регистру я изменил свойство пули на строчные буквы, и это сработало. Спасибо за ваше предложение. Непонятно, почему свойство JSON сейчас не работает.

Kevin James 17.08.2024 19:40

Другие вопросы по теме