SqlBulkCopy нарушает уникальное ограничение с неправильным значением - PullRequest
0 голосов
/ 21 ноября 2018

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

CREATE TABLE [dbo].[Site]
(
    [Id] INT NOT NULL IDENTITY(1, 1) PRIMARY KEY, 
    [Name] NVARCHAR(MAX) NOT NULL, 
    [CreatedAt] DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    [UpdatedAt] DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, 
    [DeletedAt] DATETIME NULL, 
    CONSTRAINT [AK_Site_Name] UNIQUE ([Name])
)

Я загружаю данные из файла, анализирую его, манипулирую им и загружаю обратно.Это происходит из таблицы данных, которая выглядит следующим образом:

Name | CreatedAt | UpdatedAt

Я создаю это в цикле после чтения в файле следующим образом:

DataTable dt = new DataTable() { TableName = "Site" };

var dc = new DataColumn("Name", typeof(string)) { Unique = True };
dt.Columns.Add(dc);

dc = new DataColumn("CreatedAt", typeof(DateTime));
dt.Columns.Add(dc);

dc = new DataColumn("UpdatedAt", typeof(DateTime));
dt.Columns.Add(dc);

foreach(var rec in myFile) {
    var dr = dt.NewRow();
    dr[0] = rec.SiteName;
    dr[1] = DateTime.UtcNow;
    dr[2] = DateTime.UtcNow;
    dt.Rows.Add(dr);
}

И, наконец, передаю его в SqlBulkCopy какИтак:

var connection = new SqlConnection(ConnectionString);

        var bulkCopy =
            new SqlBulkCopy
                (connection,
                    SqlBulkCopyOptions.TableLock |
                    SqlBulkCopyOptions.FireTriggers |
                    SqlBulkCopyOptions.UseInternalTransaction,
                    null
                )
            {
                DestinationTableName = "Site",
                BatchSize = 1000
            };
        connection.Open();
        bulkCopy.WriteToServer(dataTable);
        connection.Close();

Я получаю исключение, говорящее:

Нарушение ограничения UNIQUE KEY 'AK_Site_Name'.Невозможно вставить дубликат ключа в объект «dbo.Site».Значение ключа-дубликата: (21.11.2008, 5:52:13).

Проверка моей таблицы данных в отладчике показывает правильность столбцов.Нет ошибок из самой таблицы данных.

Я попытался воспроизвести это в SSMS следующим образом:

DECLARE @currentd DATETIME = CURRENT_TIMESTAMP;

INSERT INTO [dbo].[Site] (Name, CreatedAt, UpdatedAt) VALUES ('Test', @currentd, @currentd), ('Test', @currentd, @currentd)

И, конечно, как и ожидалось, все работало нормально.Это заставляет меня поверить, что каким-то образом для поля Name устанавливается дата, но я не уверен, как.

Кто-нибудь испытывал это и может указать мне правильное направление?

1 Ответ

0 голосов
/ 21 ноября 2018

dr [0] - для идентификатора столбца, который должен быть равен нулю, поэтому окончательный цикл должен выглядеть следующим образом:

foreach(var rec in myFile) {
 var dr = dt.NewRow();
 dr[0] = null;
 dr[1] = rec.SiteName;
 dr[2] = DateTime.UtcNow;
 dr[3] = DateTime.UtcNow;
 dt.Rows.Add(dr); }
...