SqlBulkCopy - неправильное преобразование DateTime - PullRequest
0 голосов
/ 01 апреля 2019

Я получаю результаты запроса из Azure Log Analytics.Результаты в Table объекте.Это все в строковом формате.В базе данных таблица имеет столбец PeriodStart, тип smalldatetime.

Приведенный ниже код работает нормально - он вставляет все данные.Но он конвертирует PeriodStart неправильно.Например, у меня есть строковое значение в строке для PeriodStart столбца "2019-03-26T00:00:00Z" - и в базе данных оно будет выглядеть "2019-03-26 02:00:00".Похоже, он использует мой часовой пояс - переводит в местное времяКак этого избежать?

public async Task BulkInsertMetrics(Table metrics)
{
    var metricsDt = new DataTable();
    metricsDt.Columns.AddRange(metrics.Columns
        .Select(c => new DataColumn(c.Name)).ToArray());
    foreach (var row in metrics.Rows)
    {
        metricsDt.Rows.Add(row.ToArray());
    }

    using (var connection = new SqlConnection(_databaseSettings.ConnectionString))
    {
        await connection.OpenAsync();
        using (var transaction = connection.BeginTransaction())
        using (var bulkCopy = new SqlBulkCopy(connection, SqlBulkCopyOptions.Default, transaction))
        {
            bulkCopy.DestinationTableName = "Metrics";
            foreach (var column in metrics.Columns)
            {
                bulkCopy.ColumnMappings.Add(column.Name, column.Name);
            }

            await bulkCopy.WriteToServerAsync(metricsDt);
            transaction.Commit();
        }
    }
}

1 Ответ

3 голосов
/ 01 апреля 2019

Когда вы передаете строку даты и времени, она должна быть проанализирована клиентским API и преобразована в целевой тип данных smalldatetime, который не имеет понятия о часовом поясе. .NET распознает строку даты и времени ISO 8601 с буквой «Z», обозначающей UTC, и по умолчанию преобразует ее в местное время. Для остроумия:

DateTime.Parse("2019-03-26T00:00:00Z") //converted to your local time
DateTime.Parse("2019-03-26T00:00:00") //no conversion

Один из способов - использовать метод ToUniversalTime(), чтобы избежать преобразования в местный часовой пояс:

DateTime.Parse("2019-03-26T00:00:00Z").ToUniversalTime()

Как правило, рекомендуется использовать DataTable с собственными типами данных, содержащими желаемое значение, чтобы иметь полный контроль над фактическим значением, вставленным в базу данных.

...