Gentle.net bugs fixing
以下是自己遇到及网上收集的gentle bug及注意点合集及解决方案,借鉴之处请务怪罪:p
Gentle.net还是有不少bug的,基本上都是Provider的细节问题,好在有源代码,自己改改就好
------------------------------------------------------------------
[Common]
------------------------------------------------------------------
表名和字段名最好不一样,否则自动生成的代码中属性名和类名会冲突
Broker.Retrieve函数若找不到值,为什么不返回null,而要抛出异常?这不太符合使用习惯
------------------------------------------------------------------
[代码生成器]
------------------------------------------------------------------
mygernation gentle.net脚本无法生成oracle数据表操作代码,不知道codesmith行不行,没试过
修改mygeneration代码。
·添加[Serializable()]特性
·添加静态删除函数,如:
public static void Remove(int id)
{
Key key = new Key(typeof(Product), true, "id", id);
Broker.Remove(typeof(Product), key);
}
·添加PrePersist()和PreRemove()虚函数(类似iBatisNet),非常实用
public override void Persist()
{
if (IsChanged || !IsPersisted)
{
PrePersist(); // Add here
base.Persist();
isChanged = false;
}
}
public override void Remove()
{
PreRemove(); // Add here
base.Remove();
}
protected virtual void PrePersist()
{
}
protected virtual void PreRemove()
{
}
------------------------------------------------------------------
[Access]
------------------------------------------------------------------
access数据表不允许取名为action, catalog,否则会报错“FROM 子句语法错误”,无论你是否调用了该表(古怪吧~)。估计是JetFactory.cs中的关键字不足
access时间字段查询有问题
------------------------------------------------------------------
[SqlServer]
------------------------------------------------------------------
NET数据类型和数据库数据类型转化:string应该转为NVarchar而不是源代码中的Varchar(在文件SQLServerFactory.cs中):
public override long GetDbType( Type type)
{
...
switch(...)
{
...
else if( type.Equals( typeof(string) ) )
result = SqlDbType.NvarChar;
else if ...
...
}
}
------------------------------------------------------------------
[Oracle]
------------------------------------------------------------------
NET数据类型和数据库数据类型转化:string应该转为NVarchar而不是源代码中的Varchar(在文件OracleFactory.cs中):
public override long GetDbType( Type type)
{
...
switch(...)
{
...
else if( type.Equals( typeof(string) ) )
result = OracleType.NvarChar;
else if ...
...
}
}
Oracle的Provider是不支持空字符串的(注:oracle就是如此,将''认为是null,会引发异常)。
若希望支持空字符串,需要更改以下函数(Client\SqlStatement.cs)
private void SetParameter( IDataParameter param, object val, FieldMap fm )
{
Check.Verify(
param.Direction == ParameterDirection.Input ||
param.Direction == ParameterDirection.InputOutput,
"Cannot set value of output parameters!" );
// do additional checking for known types
if( map != null && fm != null )
{
param.Value = GetParameterValue( val, map, fm );
// 下面这几行语句添加自 Gu Zhigang
// 解决问题:因为oracle代理驱动的原因 ,字符型数据不能插入空字符串
//if (this.Command.Connection.GetType().Name.IndexOf("Oracle",0)>=0)
{
if(param.DbType == DbType.AnsiString && param.Value.ToString()=="")
param.Value = DBNull.Value;
}
}
else // unknown type - no clipping or fancy checks, just do it
{
param.Value = val != null ? val : DBNull.Value;
}
}
虽然不是真正的解决问题,但是能用就好了,要注意的就是程序中要注意这个变化.
在OracleAnalyzer.cs中,会去数据库那里分析原有表中的每个字段、字段类型、字段长度。但分析CLOB时,将其长度定为了4000,这就不好了,长的数据会被它截断。所以,改了一下:
fm.SetDbType( sr.GetString( i, "Type" ), false );
fm.SetIsNullable( GetBoolean( sr.GetString( i, "IsNullable" ) ) );
if( sr.GetString( i,"Type") == "CLOB")
{
fm.SetSize(0);
}
else if( sr[ i, "Size" ] != null )
{
fm.SetSize( sr.GetInt( i, "Size" ) );
}