最近开发过程中遇到一个奇怪的问题,sql语句在.net代码中执行报错异常信息:Unable to convert MySQL date/time value to System.DateTime但sql语句拷贝到sqlyog里面去执行,一切正常。由此,我们不得不深入mysql驱动源码去一探究竟。当然网上已经有很多类似问题解决方案了。
先来看看别人的解决办法: mysql驱动组件,链接MySql数据库时,如果存在字段类型为date/datetime时的可能会出现以下问题 “Unable to convert MySQL date/time value to System.DateTime” 原因:可能是该字段(date/datetime)的值默认缺省值为:0000-00-00/0000-00-00 00:00:00,这样的数据读出来转换成System.DateTime时就会有问题; 解决办法: 1、将该字段的缺省值设置为null,而不是0000-00-00/0000-00-00 00:00:00的情况; 2、在链接MySQL的字符串中添加:Convert Zero Datetime=True 和 Allow Zero Datetime=True两个属性; 3、将该字段设置成字符串类型;
我们看看mysql的源码里面默认是如何处理这个值的: 0000-00-00/0000-00-00 00:00:00 下面的核心代码字体已经加粗标注好了哦! 源码文件:MySql.Data\Source\MySqlConnectionStringBuilder.cs 代码片段: #if !CF && !MONO [Category("Advanced")] [DisplayName(" Convert Zero Datetime ")] [Description("Should illegal datetime values be converted to DateTime.MinValue")] [DefaultValue(false)] [RefreshProperties(RefreshProperties.All)] #endif public bool ConvertZeroDateTime { get { return convertZeroDatetime; } set { SetValue("Convert Zero Datetime", value); convertZeroDatetime = value; } } 源码文件:MySql.Data\Source\datareader.cs 代码片段: public override DateTime GetDateTime(int i) { IMySqlValue val = GetFieldValue(i, true); MySqlDateTime dt; if (val is MySqlDateTime) dt = (MySqlDateTime)val; else { // we need to do this because functions like date_add return string string s = GetString(i); dt = MySqlDateTime.Parse(s, this.connection.driver.Version); } if (connection.Settings. ConvertZeroDateTime && !dt.IsValidDateTime) return DateTime.MinValue; else return dt.GetDateTime(); }
最后,我们看看导致错误的代码,结合上面的步骤,思路就更清晰了。 错误信息:Unable to convert MySQL date/time value to System.DateTime 在 MySql.Data.Types.MySqlDateTime.GetDateTime() 位置 MySqlDateTime.cs:行号 434 在 MySql.Data.MySqlClient.MySqlDataReader.GetValue(Int32 i) 位置 datareader.cs:行号 691 在 MySql.Data.MySqlClient.MySqlDataReader.GetValues(Object[] values) 位置 datareader.cs:行号 707 在 System.Data.Common.DbCommand.ExecuteReader() 位置 DbHelper.cs:行号 1429