EF Core не позволяет создать связь между таблицами многие ко многим, если Id одной из сущности равен 0

Рейтинг: 0Ответов: 2Опубликовано: 27.04.2023

У меня есть три таблицы, представленные сущностями:


    public class Verification
    {
        public int VerificationId { get; set; }
        public string Name { get; set; }
    }

    public class VerificationEntry
    {
        public int VerificationGroupId { get; set; }
        public int VerificationId { get; set; }
        public VerificationGroup VerificationGroup { get; set; }
        public Verification Verification { get; set; }
    }

    public class VerificationGroup
    {
        public int VerificationGroupId { get; set; }
        public string Name { get; set; }
    }

Идентификаторы могут иметь отрицательные значения и даже 0 (условия из ТЗ, ввод идентификаторов пользовательский).

При добавлении в БД средствами EF Core сущностей с идентификаторами не равными 0, всё спокойно добавляется. Если использовать 0 в качестве идентификатора, то возникает исключение. Пример исключения при попытке создать VerificationEntry между уже существующими Verification и VerificationGroup с идентификатороми 0 и 3 соответственно:

System.InvalidOperationException: 
"The value of 'VerificationEntry.VerificationId' is unknown when attempting to save changes. 
This is because the property is also part of a foreign key for which 
the principal entity in the relationship is not known.

Допустим при добавлении новой сущности с идентификатором 0 возникает и такая ошибка (логов приходит очень много, вот думаю информативная часть):

"Exception":"Microsoft.EntityFrameworkCore.DbUpdateException: 
An error occurred while saving the entity changes. 
See the inner exception for details.
\r\n ---> Npgsql.PostgresException (0x80004005): 
23505: повторяющееся значение ключа нарушает ограничение уникальности \"pk_verification_groups\"\r\n\r\n
DETAIL: Detail redacted as it may contain sensitive data. 
Specify 'Include Error Detail' in the connection string to include this information.\r\n 

При этом, ручное добавление таких данных в БД работает нормально. В чём может быть дело?

P.S. Сущностей с такими идентификаторами в БД не было для случая простого создания Verification или VerificationGroup

P.S.S При создании связи между сущностями Verification и VerificationGroup через VerificationEntry уже были соответствующие сущности с Id = 0, которые были созданы в БД вручную.

Ответы

▲ 0Принят

Мне помогло добавление атрибутов к ID моделей, которые отключают режим создания ключей базой данных. То есть база данных получает тот ID, который был отправлен сервисом. По всей видимости БД идентификатор со значением 0 обрабатывала как NULL и пыталась создать для него свой ID.

Вот как теперь выглядят мои модели:

    public class Verification
    {
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int VerificationId { get; set; }

        public string Name { get; set; }
    }

    public class VerificationEntry
    {
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int VerificationGroupId { get; set; }

        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int VerificationId { get; set; }

        public VerificationGroup VerificationGroup { get; set; }

        public Verification Verification { get; set; }
    }

    public sealed class VerificationGroup
    {
    
        [DatabaseGenerated(DatabaseGeneratedOption.None)]
        public int VerificationGroupId { get; set; }

        public string Name { get; set; }

    }
▲ 0

По-моему, там чётко написано:

23505: повторяющееся значение ключа нарушает ограничение уникальности

То есть в таблице VerificationGroup уже есть запись с таким ключом.