SqlBulkCopy - DateTime 错误转换

SqlBulkCopy - DateTime wrong conversion

我正在从 Azure Log Analytics 获取查询结果。结果在 Table 对象中。都是字符串格式。在数据库中,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();
        }
    }
}

当您传递一个日期时间字符串时,它必须由客户端 API 解析并转换为目标 smalldatetime 数据类型,它没有时区的概念。 .NET 识别带有 "Z" 表示 UTC 的 ISO 8601 日期时间字符串,默认情况下将其转换为本地时间。即:

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,这样您就可以完全控制插入数据库的实际值。