【问题标题】:"SqlDateTime overflow" error with DataSets over remoting远程处理 DataSet 时出现“SqlDateTime 溢出”错误
【发布时间】:2016-06-09 03:55:34
【问题描述】:

我们有一个基于 Web 的 Windows 窗体 (DNF2!) / 远程处理 (!) / SQL Server (2008R2!) 系统,它可以愉快地从不同的时区在 Web 上来回传递类型化的相当大和不同的数据集。

我们最近改进了系统,在用户开始收到零星的“SqlDateTime 溢出”错误(下面的堆栈跟踪)之前,情况看起来不错。零星的 i.t.o.有些表偶尔会引起问题,有些则根本不会。

我们最终发现只有在客户端和 Web 服务器时区不同时才会发生这种情况 - 落后或领先。

而且它只有在 DateTime 字段为空白时才会发生

从堆栈跟踪来看,这似乎是一个序列化问题。这在调查期间得到了证实,显示它命中了 Web 服务器上的 BL(My.Application.Log.WriteEntry 显示日期字段为日期或 NULL),但没有命中数据库(SQL Profiler 没有显示任何内容)。

我们在调试过程中确实注意到我们收到了 MDA 警告:

UTC 日期时间正在转换为仅适用于当地时间的格式的文本。这可能在使用“z”格式说明符调用 DateTime.ToString 时发生,该说明符将在输出中包含本地时区偏移量。在这种情况下,要么使用指定 UTC 时间的“Z”格式说明符,要么使用“o”格式字符串,这是在文本中保存 DateTime 的推荐方法。当传递要由 XmlConvert 或 DataSet 序列化的 DateTime 时,也会发生这种情况。如果使用 XmlConvert.ToString,则传入 XmlDateTimeSerializationMode.RoundtripKind 以正确序列化。 如果使用 DataSet,请将 DataColumn 对象上的 DateTimeMode 设置为 DataSetDateTime.Utc

我们尽职尽责地听从了 BillG 的建议(即将 DateTimeMode 更改为 UTC),但这并没有什么不同 :(

我们发现将所有 DateTime 字段更改为文本也解决了问题,尽管这让我们对其他相当严重的问题持开放态度!

因此,虽然我们有一些变通办法,但它们并不是可行的解决方案。

附注 - 我们还尝试对某些 DataSet 数据进行压缩(将整个 DataSet 转换为字节流并使用 System.IO.Compression),但在压缩的 DataSet 中并没有始终发现此错误- 此外,我们在抓着稻草的同时完全消除了压缩!

System.Data.SqlTypes.SqlTypeException: SqlDateTime overflow. Must be between 1/1/1753 12:00:00 AM and 12/31/9999 11:59:59 PM.

Server stack trace:
   at System.Data.Common.DbDataAdapter.UpdatedRowStatusErrors(RowUpdatedEventArgs rowUpdatedEvent, BatchCommandInfo[] batchCommands, Int32 commandCount)
   at System.Data.Common.DbDataAdapter.UpdatedRowStatus(RowUpdatedEventArgs rowUpdatedEvent, BatchCommandInfo[] batchCommands, Int32 commandCount)
   at System.Data.Common.DbDataAdapter.Update(DataRow[] dataRows, DataTableMapping tableMapping)
   at System.Data.Common.DbDataAdapter.UpdateFromDataTable(DataTable dataTable, DataTableMapping tableMapping)
   at System.Data.Common.DbDataAdapter.Update(DataTable dataTable)
   at K2.ADAMData.MaterialDataSetTableAdapters.MaterialTableAdapter.Update(MaterialDataTable dataTable)
   at K2.ADAMServerClasses.Material.SaveMaterials(Byte[] EncConStr, MaterialDataTable ChangesTable)
   at System.Runtime.Remoting.Messaging.StackBuilderSink._PrivateProcessMessage(IntPtr md, Object[] args, Object server, Int32 methodPtr, Boolean fExecuteInContext, Object[]& outArgs)
   at System.Runtime.Remoting.Messaging.StackBuilderSink.SyncProcessMessage(IMessage msg, Int32 methodPtr, Boolean fExecuteInContext)

Exception rethrown at [0]:
   at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
   at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
   at K2.ADAMServerClasses.Material.SaveMaterials(Byte[] EncConStr, MaterialDataTable ChangesTable)
   at K2.ADAM.MaterialEditForm.SaveData() in C:\Data\Clients\K2\Software\ADAM\Development\2.1 HHI\UI\Forms\MaterialEditForm.vb:line 279
   at K2.ADAM.MaterialEditForm.SaveButton_Click(Object sender, EventArgs e) in C:\Data\Clients\K2\Software\ADAM\Development\2.1 HHI\UI\Forms\MaterialEditForm.vb:line 551

【问题讨论】:

    标签: .net sql-server datetime remoting strongly-typed-dataset


    【解决方案1】:

    所以,在准备这个问题时,我顿悟了……

    在致力于提高性能的早期(DataSet 的序列化大约是实际数据大小的 8 倍!)我们更改了 DataSet.RemotingFormat=Binary

    好吧,如果这在显示不同的时区时不会失去情节,那就让我失望吧!

    我只能假设二进制序列化对 NULL 有一些奇怪的作用?也许它使用带有“isNull=true”属性的“1-Jan-0001”或其他什么?

    Anyhoo,更改 DataSet.RemotingFormat=XML,用户再次感到高兴 - 甚至流压缩也很有效。

    自我注意 - 不要使用带有 SQL 日期的二进制远程处理格式。

    【讨论】:

    • 感谢您回来发布您的发现
    猜你喜欢
    • 1970-01-01
    • 2011-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-11
    相关资源
    最近更新 更多