почему у нас дублируются Identifier артефактов в базе? мы же вроде защищены от этого в TryAddArtifact?
Вы задали очень хороший вопрос. Ваше предположение о том, что TryAddArtifact должен предотвращать дубликаты, верно, но только в определенном контексте. Давайте разберемся, почему дубликаты все же могут появляться в базе данных.
Проблема заключается не в самом TryAddArtifact, а в том, на основе чего он проверяет уникальность.
Метод TryAddArtifact находится в ArtifactsMapper и использует HashSet<ArtifactAggregate> для предотвращения добавления дубликатов в локальную коллекцию, которая будет отправлена в базу данных одной пачкой.
// src/CodeAlive.LSP/Mapping/ArtifactsMapper.cs:26
HashSet<ArtifactAggregate> artifactsToSave = new();
void TryAddArtifact(ArtifactAggregate artifact)
{
if (artifactsToSave.Add(artifact) == false)
{
logger.LogWarning("Artifact {ArtifactId} already exists", artifact.Identifier);
}
}Работа HashSet.Add() зависит от методов Equals() и GetHashCode() класса ArtifactAggregate. Посмотрим на их реализацию:
// src/CodeAlive.Domain/CoreModels/ArtifactAggregate.cs:148
private bool Equals(ArtifactAggregate other)
{
return Id.Equals(other.Id);
}
// src/CodeAlive.Domain/CoreModels/ArtifactAggregate.cs:167
public override int GetHashCode()
{
// ReSharper disable once NonReadonlyMemberInGetHashCode
return Id.GetHashCode();
}Как видите, HashSet проверяет уникальность по свойству Id, которое является ObjectId для MongoDB, а не по логическому идентификатору Identifier (ArtifactId).
Итог: TryAddArtifact защищает от дубликатов только в рамках одной операции сохранения и только если ObjectId одинаковый. Проблема дублирования в базе данных почти наверняка вызвана несогласованной генерацией строковых значений для ArtifactId в разных частях системы или при разных запусках, что приводит к генерации разных ObjectId и, как следствие, к созданию новых записей в базе вместо обновления существующих.