如何将DataSet.Fill与DateTime值默认为DateTimeKind.Utc?

gal*_*ets 6 .net ado.net sqlclient

我有一个应用程序,它将从SQL读取数据并通过WCF发送到客户端应用程序,方式类似于:

SqlDataAdapter da = new SqlDataAdapter( cmd )
DataSet ds = new DataSet();
da.Fill( ds );
return ds;
Run Code Online (Sandbox Code Playgroud)

所有日期/时间都以UTC格式存储在数据库中.我注意到,如果运行应用程序的计算机上的时钟偏差,客户端收到的日期/时间也会有所偏差.似乎在DateTime类型是未指定类型的情况下,WCF将在内部将其表示为本地时间,并且这样发送,因此应用程序和客户端之间的任何时间差异都将导致日期/时间移位.

我可以检索数据集并修复日期/时间字段,但是这里有人会想到一些更好的方法来填充数据集,这样每个DateTime字段都会自动成为da.Fill()上的DateTimeKind.Utc吗?

Jus*_*ant 16

如果您使用的是SQL Server 2008,那么"正确"的解决方案是使用SQL datetimeoffset数据类型而不是SQL的日期时间. datetimeoffset是SQL 2008新增的时区感知日期/时间类型,将在ADO.NET中转换System.DateTimeOffset为始终相对于UTC 的CLR 类型.这是一篇博客文章,详细介绍了这一点.MSDN上DateTimeOffset前几个搜索结果提供了额外的背景信息.

如果您无法更改SQL架构,ADO.NET会为此情况定制一个属性:DataColumn.DateTimeMode它控制在序列化数据集时是否添加本地时区(DateTimeMode=DataSetDateTime.UnspecifiedLocal默认情况下),或者是否添加了时区信息在序列化(DateTimeMode=DataSetDateTime.Unspecified)上.你想要后者.

如果我的MSDN文档的理解是正确的,你应该能够设置DateTimeMode=DataSetDateTime.UnspecifiedDataColumn数据集被填充后的问题.这应该在没有时区的情况下序列化列.

如果你想要真正正确(或者如果上面的方法不起作用),你可以DataTable提前创建并DateTimeMode=DataSetDateTime.UtcFill使用行之前设置该列.然后,您可以确保将日期发送为UTC.