Нарушение ограничения PRIMARY KEY 'xx'. Невозможно вставить повторяющийся ключ в объект 'cc'. Дубликат ключа (х) - PullRequest
0 голосов
/ 06 апреля 2020

Я пытаюсь поиграться с некоторыми SQL скриптами в довольно простом приложении.

Мой скрипт выглядит так:

CREATE TABLE [dbo].[MyTable]
(
    [Columndata1] [nvarchar] (255) NOT NULL,
    [Columndata2] [nvarchar] (max) NOT NULL,
    [Columndata3] [nvarchar] (max) NOT NULL,
    [ColumndataTime] [datetime] NOT NULL,

    CONSTRAINT [PK_MyTable] 
        PRIMARY KEY CLUSTERED ([Columndata1] ASC)
                    WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, 
                          IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, 
                          ALLOW_PAGE_LOCKS = ON) [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

ALTER TABLE [dbo].[MyTable] 
    ADD CONSTRAINT [DF_MyTable_ColumndataTime] DEFAULT (getutcdate()) FOR [ColumndataTime]
GO

Я должен быть честным и сказать: что это главным образом вдохновлено SO-ответом - длинной частью от

 WITH (PAD_INDEX... TEXTIMAGE_ON [PRIMARY] GO

... и поэтому я подозреваю, что это является причиной нарушения PK, но не уверен.

От что я вижу в других ответах SO, я не смог найти тот, который подходит для этой проблемы.

Я не нахожу PAD_INDEX, STATISTIC_NORECOMPUTE, IGNORE_DUP_KEY, ALLOW_ROW_LOCKS или любой из другие аргументы, чтобы быть проблемой, так что мне не хватает? И да, в SO-ответе on говорится, что ответ очевиден в сообщении об ошибке, но, очевидно, это не так - ну, не для меня.

Обновлено

вызов метода InsertAsync:

public class MyRepo<T, TId> : IRepository<T, TId> where T : class
{
    private readonly SqlConnection _mySqlConnection;

    public MyRepo(SqlConnection mySqlConnection) 
    {
        _mySqlConnection = mySqlConnection;
    }

    public async Task<int> Create(T t)
    {
        var result = await _mySqlConnection.InsertAsync(t);
        return result;
    }
}

Этот метод вызывается в другом классе:

public Class A
{
    private readonly IRepository<MyTable, string> _mytableRepo;
    ...
    ...
        public A(IRepository<MyTable, string> mytableRepo)
        {
            _mytableRepo = mytableRepo;
        }
    ...
    ...
    await _myTableRepo.Create(new MyTable {
        ...
        ...
        });
}

Я пытался опустить весь другой код, который я надеваю не думаю, что имеет значение в этом контексте.

1 Ответ

0 голосов
/ 06 апреля 2020

Я думаю, что у вас уже есть ответ, вы вставляете повторяющиеся значения в столбец, который вы указали в качестве первичного ключа, ошибка, которую вы получаете, говорит вам об этом, и все это особенно ясно. Я вижу, что вы предполагали, что происходило что-то более «зловещее», но, похоже, это было не так, и это не было «состояние расы» или что-то более сложное.

Однако, Я подумал, что, возможно, стоит указать на что-то, что я воспринимаю как «красный флаг». Может быть, это не классифицируется как ответ, но затрагивает некоторые моменты в вашем первоначальном вопросе, особенно когда вы начинаете спрашивать об опциях в «сложной» части вашего CREATE TABLE сценария, и это слишком долго для комментария?

Если у вас есть «по умолчанию» из установки «1022 * Server», тогда 90% операторов в вашем скрипте CREATE TABLE являются просто избыточными значениями по умолчанию.

Я могу запустить это script:

CREATE TABLE [dbo].[MyTable] (
    [Columndata1] [nvarchar] (255) NOT NULL,
    [Columndata2] [nvarchar] (max) NOT NULL,
    [Columndata3] [nvarchar] (max) NOT NULL,
    [ColumndataTime] [datetime] NOT NULL,
    CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED ([Columndata1]));

Затем я могу сгенерировать скрипт создания для таблицы непосредственно из SSMS, чтобы получить:

SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[MyTable](
    [Columndata1] [nvarchar](255) NOT NULL,
    [Columndata2] [nvarchar](max) NOT NULL,
    [Columndata3] [nvarchar](max) NOT NULL,
    [ColumndataTime] [datetime] NOT NULL,
 CONSTRAINT [PK_MyTable] PRIMARY KEY CLUSTERED 
(
    [Columndata1] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO

Этот второй скрипт очень похож на тот, что в вашем опубликовать сейчас, не так ли?

Теперь нет ничего плохого в том, чтобы указать все эти параметры по умолчанию, и есть случаи, когда это может закончиться вашим преимуществом, но моим личным предпочтением (и предпочтением всех, кого я когда-либо работал) опускает параметры по умолчанию, так как они просто усложняют рецензирование сценариев и, по сути, "беспорядочно". Вы можете спорить о том, стоит ли указывать ASC в разделе PRIMARY KEY или нет, некоторые из них предполагаемые знания, и всегда есть вероятность, что Microsoft может решить изменить значения по умолчанию в будущем (и тогда первый сценарий будет не генерировать то, что вы хотели). Однако, с прагматической точки зрения c о том, как эти вещи работают, шансы Microsoft изменить эти параметры в будущей версии невероятно малы, поскольку это сломало бы так много баз данных, которые используются в дикой природе.

Возьмите это как хотите, но я подумал, что стоит объяснить это, поскольку вы, кажется, немного зациклены (может быть, неправильное слово :)) на «длинной части» (ваши слова) в исходном запросе?

...