SqlBulkCopy-DateTime错误转换

时间:2019-04-01 10:07:46

标签: c# sql-server ado.net sqlbulkcopy

我从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 个答案:

答案 0 :(得分:3)

传递日期时间字符串时,必须由客户端API对其进行解析,并将其转换为目标smalldatetime数据类型,该数据类型没有时区的概念。 .NET可以识别带U的“ Z”的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与包含所需值的本机数据类型一起使用,以便完全控制插入数据库中的实际值。