【问题标题】:SqlBulkCopy - DateTime wrong conversionSqlBulkCopy - DateTime 错误转换
【发布时间】:2019-04-01 10:07:45
【问题描述】:

我从 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();
        }
    }
}

【问题讨论】:

  • 在源数据表中使用强类型的日期时间列来避免解析和字符串格式问题。
  • 好的,手动转换有帮助。我在解析字符串后使用了ToUniversalTime()。谢谢。
  • 我用答案扩展了您的解决方案。

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


【解决方案1】:

当你传递一个日期时间字符串时,它必须被客户端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 和包含所需值的本机数据类型,这样您就可以完全控制插入到数据库中的实际值。

【讨论】:

    猜你喜欢
    • 2016-03-17
    • 1970-01-01
    • 1970-01-01
    • 2012-08-16
    • 2014-01-08
    • 2015-09-05
    • 2019-12-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多