我们用的是SQLServer2008, 有一个字段,我用的是 Time 类型(这个类型是2008新加的)。
上周末快下班的时候,我运行改版为 .NET 3.5 的新网站,报:
Object must implement IConvertible.
这个错误,很令我郁闷,周末居然做梦都梦到它。
从具体的错误里根本看不出来是哪个地方出错。只有猜大头了。数据表里基本都是 int, varchar, datetime ,只有这一个字段是 time 类型,就猜它了,把它的类型改为 varchar,运行,通过。
但是现在还不能更改数据库,因为老版本的网站还在运行。
那只好自己动手添加支持了。
忘了说环境了:
SubSonic 3, .NET 3.5 SQLServer2008
SubSonic 3 是在 SQLServer.ttinclude 文件的 GetSysType 和 GetDbType 这两个方法里做的类型映射。
所以只需要添加:
case "time":
sysType = "TimeSpan";
break;
和
case "time":
return DbType.Time;
到对应的方法里就行了。
做完这些之后,我以为就此完工了呢,谁知道选出来的那个字段(就是上面我说的 Time 类型,映射为 TimeSpan 的那个字段)根本就没有值。看看 SubSonic 生成的 SQL 语句,居然没有这个字段。
怎么办呢?
跟踪调试了N回,找到了问题的所在:
在 SubSonic 3 的源代码:QueryLanguage.cs 的 IsScala 方法里,修改:
case TypeCode.Object:
return
type == typeof(DateTime) ||
type == typeof(DateTimeOffset) ||
type == typeof(decimal) ||
type == typeof(Guid) ||
type == typeof(byte[])
这一段,修改为:
case TypeCode.Object:
return
type == typeof(DateTime) ||
type == typeof(DateTimeOffset) ||
type == typeof(decimal) ||
type == typeof(Guid) ||
type == typeof(byte[]) ||
type == typeof(TimeSpan)
即:添加了 type== typeof(TimeSpan)
在运行,OK,问题解决。
本以为改改 SQLServer.ttinclude 文件就行了,结果还修改了 SubSonic 的源码。
因为我要华丽转身,这个项目过不了多久就要转给别人做了,所以对 SubSonic 的修改,还是放弃吧,免得我转身之后,接手的人不知所以然。
------------------------------------------
上面只说了读取,但是在更新的时候,会出另外一个问题, TimeSpan 会尝试着转成 DateTime ,
SubSonic 的 DbDataProvider.cs 的 AddParams 方法里有如下:
p.DbType = param.DataType;
如果 param.DataType 为 DbType.Time 的话,运行过这一句之后, p.DbType 居然是 DbType.DateTime
这就导致了试图从 TimeSpan 转换为 DateTime。
这样是不行的,怎么办呢?
紧接着下面有一个判断。
else if(param.DataType == DbType.Guid)
我就在这个 else if 后面在加一个判断吧:
else if( param.DataType == DbType.Time ){
p.Value = param.ParameterValue.ToString();
}
然后运行,正确通过,查看数据表,数据以修改。
| < Prev | Next > |
|---|
Last Updated ( Monday, 26 July 2010 12:19 )



