zoukankan      html  css  js  c++  java
  • 拜读websharp时,发现的几处问题(一)

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

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

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

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

     1
     2 /**/
    11 internal object  ConvertOracle(object obj,System.Type type)
    12 {
    13  object strReturn = obj;
    14
    15  if ((type == typeof(System.String)) && (obj.ToString() == ""))
    16  {
    17   strReturn = System.DBNull.Value ;
    18  }

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

    24  
    25  return strReturn;
    26 }

    27
    28


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

    1 // XXX 2006-2-22 11:35:32 完成Oracle数据转换
    2 object objvalue;
    3 objvalue = Value ;
    4 objvalue = this.ConvertOracle(objvalue,objvalue.GetType());
    5 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 /// XXX 2006-2-22 15:24:53 修改加入直接访问DataAccess层的接口
    2 DataAccess GetDataAccess();
    3 
    1
    2 public DataAccess GetDataAccess()
    3 {
    4  return this.dao;
    5 }


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

     1
     2 /// <summary>
     3 /// 获取数据库连接属性
     4 /// </summary>
     5 /// <param name="ci"></param>
     6 /// <returns></returns>

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

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

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

    61    catch
    62    {
    63     currentTrans.Rollback();
    64     throw;
    65    }

    66            }

    67            else
    68            {
    69                throw new Exception("指定类型不是一个实体类。");
    70            }

    71        }

    72
    73

        

  • 相关阅读:
    iPhone开发应用Sqlite使用手册
    2.23 Apps must follow the iOS Data Storage Guidelines or they will be rejected
    跨浏览器(IE/FF/OPERA)JS代码小结
    c#一次数据库查询,JS实现内容分页
    oracle PLSQL /sqlserver2005基本操作对比
    SqlParameter构造函数的临界边缘
    SQL SERVER 2005分页存储过程
    *自创*可变长度随机数字/字母的生成小结(针对文件上传及验证码)
    Visual Source Safe连接数据文件图解 解决密码缓存问题
    [Ubuntu] Invalid command 'VirtualDocumentRoot', perhaps misspelled or defined by a module not included in the server configuration
  • 原文地址:https://www.cnblogs.com/linfuguo/p/336660.html
Copyright © 2011-2022 走看看