zoukankan      html  css  js  c++  java
  • Database2Sharp生成的Enterprise Library架构对Oracle自动增长列字段的支持

    自动增长的主键字段是个好东西,提供了一个比较有意义和可阅读的字段内容(相对GUID来说),插入的时候,不用管它的值,数据库自动追加;但它也是一个不好的东西,如果管理不好,可能会造成冲突。本文暂且不讨论其优劣,因为存在就是硬道理,很多时候,我们都是采用自增长字段的,特别是对于SqlServer数据开发来说。

     本文阐述一下在Database2Sharp(软件下载地址:http://www.iqidi.com/database2sharp.htm生成的Enterprise Library架构如何实现Oracle的自增长的支持。同时也会顺带说说对SqlServer、Access的实现。

     Database2Sharp生成的Enterprise Library架构其实对Oracle内置了对自增长序列的支持,在数据库访问层的基类BaseDAL中,我们看到下面的代码。

         /// <summary>

        /// 数据访问层的基类
        
    /// </summary>
        public abstract class BaseDAL<T> : IBaseDAL<T> where T : BaseEntity, new()
        {
            
    #region 构造函数

            
    protected string tableName;//需要初始化的对象表名
            protected string primaryKey;//数据库的主键字段名
            protected string sortField = "ID";//排序字段
            private bool isDescending = false;//

            
    protected string selectedFields = " * ";//选择的字段,默认为所有(*)
            private string seqField = "";//指定那个字段是用序列来控制它的值的,一般为主键
            private string seqName = "";//指定的序列名称,建议规则为:SEQ_表名称
            
            
    /// <summary>
            
    /// 指定那个字段是用序列来控制它的值的,一般为主键
            
    /// </summary>
            public string SeqField
            {
                
    get { return seqField; }
                
    set { seqField = value; }
            }

            
    /// <summary>
            
    /// 指定的序列名称,建议规则为:SEQ_表名称
            
    /// </summary>
            public string SeqName
            {
                
    get { return seqName; }
                
    set { seqName = value; }
            }


    这段代码定义了两个属性,一个是序列字段名称(一般是主键,如ID),一个是我们为该字段指定的序列对象名称,我们这里建议的名称是"SEQ_表名称",当然也可以使用任意的名称,合理统一就可以了。这两个属性在基类不需要修改,只需要在具体的数据访问对象(如数据访问层中的Customer类)构造函数中,指定序列字段和序列对象即可。

    下面我们看看表盒序列的脚本代码,例如我创建一个客户表,其字段ID为自增序列,我的创建脚本是。

     create table ALL_CUSTOMER

    (
      ID          NUMBER not null,
      USERNUMBER  VARCHAR2(50),
      NAME        VARCHAR2(50),
      TYPE        VARCHAR2(50),
      AREA        VARCHAR2(50),
      COMPANY     VARCHAR2(50),
      ADDRESS     VARCHAR2(50),
      TELEPHONE1  VARCHAR2(50),
      TELEPHONE2  VARCHAR2(50),
      TELEPHONE3  VARCHAR2(50),
      TELEPHONE4  VARCHAR2(50),
      TELEPHONE5  VARCHAR2(50),
      CREATEDATE  DATE,
      SHOP_ID     VARCHAR2(50),
      NOTE        VARCHAR2(255),
      LASTUPDATED DATE,
      
    constraint PK_ALL_CUSTOMER primary key (ID)
    );

    create sequence SEQ_ALL_CUSTOMER
    minvalue 1
    maxvalue 999999999999999999999999999
    start with 1220
    increment by 1
    cache 20;

    commit;

    注意SEQ_ALL_CUSTOMER就是序列对象名称,那么我们再插入的时候,应该如何写入序列字段的值,并且获得新的值作为返回值的呢?

    在BaseDAL中,有一个Insert2的方法,是专门处理 自增序列函数,并且返回创建记录的自增字段的值的,我们来看看其源码。

             /// <summary>

            /// 添加记录
            
    /// </summary>
            
    /// <param name="recordField">Hashtable:键[key]为字段名;值[value]为字段对应的值</param>
            
    /// <param name="targetTable">需要操作的目标表名称</param>
            
    /// <param name="trans">事务对象,如果使用事务,传入事务对象,否则为Null不使用事务</param>
            public int Insert2(Hashtable recordField, string targetTable, DbTransaction trans)
            {
                
    int result = -1;
                
    string fields = ""// 字段名
                string vals = ""// 字段值
                if (recordField == null || recordField.Count < 1)
                {
                    
    return result;
                }

                List<OracleParameter> paramList = new List<OracleParameter>();
                IEnumerator eKeys = recordField.Keys.GetEnumerator();

                
    while (eKeys.MoveNext())
                {
                    
    string field = eKeys.Current.ToString();
                    fields += field + ",";
                    
    if (!string.IsNullOrEmpty(seqField) && !string.IsNullOrEmpty(seqName)
                        
    && (field == seqField))
                    {
                        vals += string.Format("{0}.NextVal,", seqName);
                    }
                    
    else
                    {
                        vals += string.Format(":{0},", field);
                        
    object val = recordField[eKeys.Current.ToString()];
                        paramList.Add(new OracleParameter(":" + field, val));
                    }
                }

                fields = fields.Trim(',');//除去前后的逗号
                vals = vals.Trim(',');//除去前后的逗号
                string sql = string.Format("INSERT INTO {0} ({1}) VALUES ({2})", targetTable, fields, vals);

                Database db = DatabaseFactory.CreateDatabase();
                DbCommand command = db.GetSqlStringCommand(sql);
                command.Parameters.AddRange(paramList.ToArray());

                
    if (trans != null)
                {
                    db.ExecuteNonQuery(command, trans);

                    sql = string.Format("SELECT {0}.Currval ID From Dual", seqName);
                    command = db.GetSqlStringCommand(sql);
                    result = Convert.ToInt32(db.ExecuteScalar(command, trans).ToString());
                }
                
    else
                {
                    db.ExecuteNonQuery(command);

                    sql = string.Format("SELECT {0}.Currval ID From Dual", seqName);
                    command = db.GetSqlStringCommand(sql);
                    result = Convert.ToInt32(db.ExecuteScalar(command).ToString());
                }

                
    return result;
            }

    其中我们判断是否有自增序列ID和其名称(非空字符),如果有则使用这段代码,来写入自增序列的下一个值NextVal(新增值),作为这个字段的值。

    vals += string.Format("{0}.NextVal,", seqName); 

     如果要返回插入的自增序列值,那么我们使用序列对象的Currval 就可以了。下面是返回插入的字段内容。

    sql = string.Format("SELECT {0}.Currval ID From Dual", seqName); 

    这样对于写入新的自增长值并返回就实现了。


    对SqlServer和Access自增长字段的支持 

    对于SqlServer,实现自增长字段就更加方便了,由于没有Oracle序列对象那么麻烦,所以只需要在具体的数据库访问对象中,构建写入字段的Hash表中,忽略该字段就可以了(代码已经自动生成,不用管理的)。其返回刚刚插入的自增内容,则在插入的语句后面增加一条语句就可以了,语句如下。

     SELECT SCOPE_IDENTITY()

    对于Access的数据库,原理和SqlServer一样,不过需要返回刚刚插入的自增长值的时候,使用这段语句就可以了。

     SELECT @@IDENTITY

     对于SqlServer和Access,只要设计好数据库的自增字段,自动生成的代码中,数据访问类是不用修改任何信息,就可以完美支持自增序列。

    主要研究技术:代码生成工具、会员管理系统、客户关系管理软件、病人资料管理软件、Visio二次开发、酒店管理系统、仓库管理系统等共享软件开发
    专注于Winform开发框架/混合式开发框架Web开发框架Bootstrap开发框架微信门户开发框架的研究及应用
      转载请注明出处:
    撰写人:伍华聪  http://www.iqidi.com 
        
  • 相关阅读:
    OO第二单元——多线程(电梯)
    OO前三次作业思考(第一次OO——Blog)
    P2016 战略游戏——树形DP大水题
    P1108 低价购买——最长下降子序列+方案数
    P1041 传染病控制——暴力遍历所有相同深度的节点
    P2502 [HAOI2006]旅行——暴力和并查集的完美结合
    2019.10.25字符串——zr
    P3719 [AHOI2017初中组]rexp——递归模拟
    树状数组优化最长上升子序列
    P1378 油滴扩展——搜索小记
  • 原文地址:https://www.cnblogs.com/wuhuacong/p/1587328.html
Copyright © 2011-2022 走看看