拜读websharp时,发现的几处问题(一)

     近日拜读了孙兄(http://sunnyym.cnblogs.com/)的大作websharp,感受了此ORM框架设计思想,但同时也发现一些小问题,顺便提出来,供大家交流之用,若有理解偏差或理解错误之处,还望海涵^-^。
  
     接触此框架有一段时间了,一直以来都没时间细读,近来有机会细读一下,收获颇丰,但同时也发现里面的一些小问题,也许是由于我测试的数据库是用的oracle,于是便记录下来供大家讨论参考,错误之处,还请批评指正,再者就是希望此框架能够不断进步,茁壮成长,我认为只由不断有发现问题,分析问题,解决问题,才能集思广益,不断发展。

     1.先说一处失误,在Websharp.Data项目中OracleDataAccess.cs文件,属性DatabaseType应为Oracle,可能作者直接从MSSQLServer复制过来,没时间去理会这此东东^-^.
    
     2.由于不同数据库数据访问时有一定的差异,所以对应的查询参数应该按不同数据库类型有所区分,比如:Oracle数据库在对字符串空值的处理方面就与SqlServer不同,Oracle中是用null来对String的空值存储的,若有下面的例子:

1 None.gif  T1 t1  =  EntityManager.CreateObject( typeof (T1))  as  T1;
2 None.gif t1.A  =   " 3333 " ;
3 None.gif t1.B  =   null ;
4 None.gif t1.C  =   "" ;

     如果对上面的实体进行执行,就会出现错误,因为Oracle不能直接对像t1.C这样的空值进行处理,如果改为t1.C = null则不会出现错误,而SQLServer中则直接可以,所以在参数查询时需要对Oracle进行转换,下面就是一种较简单的一种处理方式,在Websharp.Data项目的QueryParameter.cs文件中加入一个简单处理函数及一些处理代码

 1 None.gif
 2 ExpandedBlockStart.gifContractedBlock.gif  /**/ /// <summary>
 3InBlock.gif /// 方法名称: ConvertOracle
 4InBlock.gif /// 内容描述: 完成当前参数的Oracle转换
 5InBlock.gif /// 实现流程: 
 6InBlock.gif /// 作    者: XXX
 7InBlock.gif /// 日    期: 2006-2-22 11:24:16
 8InBlock.gif /// </summary>
 9InBlock.gif /// <param name="obj">需要转换的对象</param>
10ExpandedBlockEnd.gif /// <param name="type">当前对象类型</param>

11 None.gif   internal   object   ConvertOracle( object  obj,System.Type type)
12 ExpandedBlockStart.gifContractedBlock.gif  dot.gif {
13InBlock.gif  object strReturn = obj;
14InBlock.gif
15InBlock.gif  if ((type == typeof(System.String)) && (obj.ToString() == ""))
16ExpandedSubBlockStart.gifContractedSubBlock.gif  dot.gif{
17InBlock.gif   strReturn = System.DBNull.Value ;
18ExpandedSubBlockEnd.gif  }

19InBlock.gif  else if (type == typeof( System.DateTime ))
20ExpandedSubBlockStart.gifContractedSubBlock.gif  dot.gif{
21InBlock.gif   System.DateTime time = Convert.ToDateTime( obj );
22InBlock.gif   strReturn = time.ToString("yyyy-MM-dd HH:mm:ss");
23ExpandedSubBlockEnd.gif  }

24InBlock.gif  
25InBlock.gif  return strReturn;
26ExpandedBlockEnd.gif }

27 None.gif
28 None.gif


 在方法InitRealParameter中Oracle的处理项下加入下面代码:

1 None.gif   //  XXX 2006-2-22 11:35:32 完成Oracle数据转换
2 None.gif   object  objvalue;
3 None.gif objvalue  =  Value ;
4 None.gif objvalue  =   this .ConvertOracle(objvalue,objvalue.GetType());
5 None.gif Value  =  objvalue;


     上面的方法只能完成一些简单差异转换,其它一些差异可以参考一些其它开源的ORM框架。
    
     3,在Oracle中自增量的ID是通过Sequence实现的,所以也需要对此进行特殊处理,其实也就是执行一个SQL语句获取就OK
     既然是执行SQL语句,我们当然可以直接定义DataAccess访问对象,但出于对框架的整体性与可维护性考虑,最好不这样做,
     因为有PersistenceManager接口,应当用此接口进行数据持久化操作。
    
     在PersistenceManager接口中,已经有一个DataAccess NewDataAccess(),此项为新建一个访问对象,其实此接口在构造函数中
     已经实例化过一个DataAccess,应该不用再创建新的访问对象了,直接获取当前持久层管理对象PersistenceManager内部的访问
     对象岂不更好。于是应该在PersistenceManager接口中增加一个访问接口GetDataAccess(),当然对象的实现SingleTablePM.cs文件
     也要实现返回当前的数据访问对象。
    
     处理方式为:在Websharp.ORM.Base项目的PersistanceManager.cs文件及SingleTablePM.cs文件中增加如下代码:

1 ExpandedBlockStart.gif ContractedBlock.gif   /**/ /// XXX 2006-2-22 15:24:53 修改加入直接访问DataAccess层的接口
2 None.gif  DataAccess GetDataAccess();
3 None.gif 

 

1 None.gif
2 None.gif  public  DataAccess GetDataAccess()
3 ExpandedBlockStart.gifContractedBlock.gif  dot.gif {
4InBlock.gif  return this.dao;
5ExpandedBlockEnd.gif }


 获取Sequence的方法(直接执行SQL语句)如下:

 1 None.gif
 2 ExpandedBlockStart.gifContractedBlock.gif  /**/ /// <summary>
 3InBlock.gif /// 获取数据库连接属性
 4InBlock.gif /// </summary>
 5InBlock.gif /// <param name="ci"></param>
 6ExpandedBlockEnd.gif /// <returns></returns>

 7 None.gif   public   static  DatabaseProperty GetDatabaseProperty(CultureInfo ci)
 8 ExpandedBlockStart.gifContractedBlock.gif  dot.gif {
 9InBlock.gif  string ciPostfix = null;
10InBlock.gif  if (ci != null)
11InBlock.gif   ciPostfix = "." + ci.Name;
12InBlock.gif  DatabaseProperty dp = new DatabaseProperty();
13InBlock.gif  string databaseType = ConfigurationSettings.AppSettings["AppDB.DatabaseType" + ciPostfix];
14InBlock.gif  dp.DatabaseType = (DatabaseType) Enum.Parse(typeof(DatabaseType),
15InBlock.gif   (databaseType == null ? "Oracle" : databaseType), true);
16InBlock.gif  dp.ConnectionString = ConfigurationSettings.AppSettings["AppDB.ConnectionString" + ciPostfix];
17InBlock.gif  return dp;
18ExpandedBlockEnd.gif }

19 ExpandedBlockStart.gifContractedBlock.gif  /**/ /// <summary>
20InBlock.gif        /// 使用数据库定义的序列对象为实体生成新的Id值。访问数据库中所有实体表对应的序列对象。
21InBlock.gif        /// </summary>
22InBlock.gif        /// <param name="entityType">实体类型。</param>
23InBlock.gif        /// <param name="CultureInfo">多语言参数,System.Threading.Thread.CurrentThread.CurrentCulture</param>
24InBlock.gif        /// <returns>返回生成的唯一Id。</returns>
25InBlock.gif        /// <remarks>
26InBlock.gif        /// 实现流程:
27InBlock.gif        ///     1.使用反射机制获取实体类型绑定的TableMap属性,获取实体类型对应的表和关键字。
28InBlock.gif        ///     2.使用PersistenceManager直接执行查询调用表对应的序列对象生成Id值。
29InBlock.gif        ///       注:默认数据库设计时已经为每个实体表定义了序列对象,并且序列对象命名
30InBlock.gif        ///           满足以下格式:
31InBlock.gif        ///               S_[表名]
32ExpandedBlockEnd.gif        /// </remarks>

33 None.gif          public   static   long  GenerateIdentity(Type entityType,CultureInfo ci)
34 ExpandedBlockStart.gifContractedBlock.gif         dot.gif {
35InBlock.gif            object[] attributes = entityType.GetCustomAttributes(typeof(TableMapAttribute), true);
36InBlock.gif            if (attributes != null && attributes.Length > 0)
37ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
38InBlock.gif                TableMapAttribute tableMap = (TableMapAttribute) attributes[0];
39InBlock.gif                string sql = string.Format("SELECT S_{0}.nextval FROM DUAL", tableMap.TableName);
40InBlock.gif
41InBlock.gif    PersistenceManager pm = 
42InBlock.gif     PersistenceManagerFactory.Instance().CreatePersistenceManager(GetDatabaseProperty(ci));
43InBlock.gif
44InBlock.gif    DataAccess da = pm.GetDataAccess();
45InBlock.gif
46InBlock.gif    Transaction currentTrans ;
47InBlock.gif    currentTrans = pm.CurrentTransaction;
48InBlock.gif
49InBlock.gif    currentTrans.Begin();
50InBlock.gif
51InBlock.gif    try
52ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
53InBlock.gif     long logidentity;
54InBlock.gif
55InBlock.gif     logidentity = Convert.ToInt64(da.ExecuteScalar(sql));
56InBlock.gif
57InBlock.gif                    currentTrans.Commit();
58InBlock.gif
59InBlock.gif     return logidentity;
60ExpandedSubBlockEnd.gif    }

61InBlock.gif    catch
62ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
63InBlock.gif     currentTrans.Rollback();
64InBlock.gif     throw;
65ExpandedSubBlockEnd.gif    }

66ExpandedSubBlockEnd.gif            }

67InBlock.gif            else
68ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
69InBlock.gif                throw new Exception("指定类型不是一个实体类。");
70ExpandedSubBlockEnd.gif            }

71ExpandedBlockEnd.gif        }

72 None.gif
73 None.gif

    

转载于:https://www.cnblogs.com/linfuguo/archive/2006/02/24/336660.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值