Winform开发框架中贯彻三种数据库类型切换以及分拆数据库的帮忙

在不少用到种类里面,即使一般选用一种数据库运行,然而出于各类情状的急需,可能工作系统会计划在差距档次的数据库上,如果开发的系列能够很便宜支持七种数据库的切换,那可以为我们收缩过多困扰,同时增强系统的适应性和强壮型。还有一种情形,由于作业数据库的不停膨胀或者福利数据库的切割隔离,有时候也会把不一致的政工数据库举行分拆,如权限提供数据库,客户关系管理数据库,工作流程数据库,集团营运数据库等等,由此在一个系统内部,同时拔取2个或者以上的数据库的情况也是部分。针对这几种情形,本文介绍在自家的Winform开发框架(也利用本人的其他框架),怎么着具体处理这多个难题的。

在自家的种种开支框架之中,底层都是利用同一种数据库的访问格局,就是选择了Enterprise
Library的数据库访问模块,那么些是微软开源的公司应用模块,里面种种应用模块,都堪称是支付的一级实践。当然利用内部的数据库访问模块,是很常见的,这么些数据库访问模块,可以通过布置的点子接济各个数据库的变更。因而整合到本人的Winform开发框架之中,也很简单完结这种多数据库的章程处理。

Winform开发框架,常见的道岔形式,可以分为UI层、BLL层、DAL层、IDAL层、Entity层、公用类库层等等,B/S的Web开发框架也是提供类似的架构形式,它们只是Web界面层有所分裂,那样就给我们提供了一个统一性的费用方式,使得开发起来尤其飞快,统一性更好。框架界面层以下的架构设计图如下所示。

图片 1

1、援救多数据库的装置

1)数据库访问基类的摸底

为了介绍帮助种种数据库的方式,大家须要先来询问下任何框架的层次结构。

AbstractBaseDAL是空虚了具备数据库完结的特等基类。

BaseDALSQL是本着SqlServer数据库部分调整基类(很小的调整)。

BaseDALSQLite是针对Sqlite数据库的部分调整基类(很小的调动)。

BaseDALMySql是指向MySqlite数据库的局地调整基类(很小的调动)。

BaseDALAccess是本着Access数据库的一些调整基类(很小的调整)。

IBaseDAL是所有基础数据库访问类的接口。

多少访问接口完毕层(如Customer)和接口定义层(ICustomer)一样,都有一个基类,如按照SqlServer完成的基类为BaseDALSQL,那个基于SqlServer的多寡访问基类,它也是三番五次自一个超级级基类(大部分的贯彻在此处)AbstractBaseDAL。他们之间的接续关系如下所示

图片 2

而大家刚刚在品种工程的图中间看到,BaseDALSQL、IBaseDAL、AbstractBaseDAL那些类库由于拥有很大的通用性,为了削减在分化的项目中展开复制导致维护难点,由此大家任何把那么些时常采用到的基类或者接口,抽取到一个单身的类库里面,为了和一般的DotNET公用类库命名举行区分(WHC.Framework.Commons),大家把它定名为WHC.Framework.ControlUtil。

2)多数据库的代码已毕

为了促成多数据库的支撑,大家要求在配备文件之中读取相关的安顿,看具体是构造那种该数据库的,然后进行初步化不一致的次序集类,从而达成调用不一样数据库类型的数据库访问类。

在BaseBLL的Init函数里面的贯彻代码如下所示。

            #region 根据不同的数据库类型,构造相应的DAL层
            AppConfig config = new AppConfig();
            string dbType = config.AppConfigGet("ComponentDbType");
            if (string.IsNullOrEmpty(dbType))
            {
                dbType = "sqlserver";
            }
            dbType = dbType.ToLower();

            string DALPrefix = "";
            if (dbType == "sqlserver")
            {
                DALPrefix = "DALSQL.";
            }
            else if (dbType == "access")
            {
                DALPrefix = "DALAccess.";
            }
            else if (dbType == "oracle")
            {
                DALPrefix = "DALOracle.";
            }
            else if (dbType == "sqlite")
            {
                DALPrefix = "DALSQLite.";
            }
            else if (dbType == "mysql")
            {
                DALPrefix = "DALMySql.";
            }
            #endregion

            this.dalName = bllFullName.Replace(bllPrefix, DALPrefix);//替换中级的BLL.为DAL.,就是DAL类的全名
            baseDal = Reflect<IBaseDAL<T>>.Create(this.dalName, dalAssemblyName);//构造对应的DAL数据访问层的对象类

在切实的工作对象的调用的时候,大家不明白它实际是调用哪个数据库的拍卖类进行拍卖的,只须要调用它的功底接口就可以了,如下是界面层的有的调用代码。

            //删除关联的附件
            if (!string.IsNullOrEmpty(ids))
            {
                string[] idArray = ids.Split(',');
                foreach (string id in idArray)
                {
                    InformationInfo info = BLLFactory<Information>.FindByID(id);
                    if (info != null && !string.IsNullOrEmpty(info.Attachment_GUID))
                    {
                        BLLFactory<FileUpload>.Instance.DeleteByAttachGUID(info.Attachment_GUID);
                    }
                }
            }

在切切实实的配备文件之中,大家就足以根据须求安插好不无关系的数据库了。

根据Enterprise Library的配备,大家只要制定了<dataConfiguration
defaultDatabase=”sqlserver”>,那么就会收获sqlServer的节点,而代码通过解析ComponentDbType配置项,就足以社团对应的数据库访问对象了。两者合一就可以正确获取四处理目标,并成功拍卖数据库的访问。

<configuration>
  <configSections>
    <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data"/>
  </configSections>
  <connectionStrings>
    <add name="sqlserver" providerName="System.Data.SqlClient" connectionString="Persist Security Info=False;Data Source=(local);Initial Catalog=MVCWebMis;Integrated Security=SSPI"/>
    <add name="access" providerName="System.Data.OleDb" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|\ComponentData.mdb;User ID=Admin;Jet OLEDB:Database Password=;"/>
    <add name="sqlite" providerName="System.Data.SQLite" connectionString="Data Source=|DataDirectory|\ComponentData.db;Version=3;"/>
    <add name="oracle" providerName="System.Data.OracleClient" connectionString="Data Source=whcdb;User ID=whc;Password=whc"/>
  </connectionStrings>
  <dataConfiguration defaultDatabase="sqlserver">
    <providerMappings>
      <add databaseType="EntLibContrib.Data.SQLite.SQLiteDatabase, EntLibContrib.Data.SqLite" name="System.Data.SQLite"/>
    </providerMappings>
  </dataConfiguration>

  <appSettings>
    <!--组件的数据库类型:access、sqlserver、sqlite等-->
    <add key="ComponentDbType" value="sqlserver"/>

 

2、帮助分拆不一致数据库的装置

上边介绍的艺术,一次性只好访问一个数据库,因而默许在代码构造数据库访问对象的时候,是透过下边的代码举行的。

Database db = DatabaseFactory.CreateDatabase();

诸如此类每一趟只会拿走defaultDatabase设置的数据库进行布局,即便大家在一个系统里头,同时帮衬两个数据库的访问,那么大家应当怎么处理啊。

在框架的基类AbstractBaseDAL里面,大家对结构数据库的代码进行了包装。

        /// <summary>
        /// 根据配置数据库配置名称生成Database对象
        /// </summary>
        /// <returns></returns>
        protected virtual Database CreateDatabase()
        {
            Database db = null;
            if (string.IsNullOrEmpty(dbConfigName))
            {
                db = DatabaseFactory.CreateDatabase();
            }
            else
            {
                db = DatabaseFactory.CreateDatabase(dbConfigName);
            }
            return db;
        }

而种种DAL层都会接二连三自AbstractBaseDAL,那样也就可以透过在DAL层指定dbConfigName进行利用不一致的数据库的了。

只是如此难题应运而生了,假设大家有5个不一样类型(SqlServer、Oracle、Mysql、Access、Sqlite)的数据库的DAL层,那么每个DAL层的完毕类都要写一些代码,那样挺不便宜,那么是不是可以把它抽象到BLL层,那样只写一回配置就足以了,那些思路很好,我们实际来看望哪些促成。

1)在IBaseDAL层定义接口

    /// <summary>
    /// 数据访问层的接口
    /// </summary>
    public interface IBaseDAL<T> where T : BaseEntity
    {
        /// <summary>
        /// 设置数据库配置项名称
        /// </summary>
        /// <param name="dbConfigName">数据库配置项名称</param>
        void SetDbConfigName(string dbConfigName);

        .............
    }

2、在AbstractBaseDAL添加默许完结代码

    /// <summary>
    /// 数据访问层的超级基类,所有数据库的数据访问基类都继承自这个超级基类,包括Oracle、SqlServer、Sqlite、MySql、Access等
    /// </summary>
    public abstract class AbstractBaseDAL<T> where T : BaseEntity, new()
    {
        /// <summary>
        /// 设置数据库配置项名称
        /// </summary>
        /// <param name="dbConfigName">数据库配置项名称</param>
        public virtual void SetDbConfigName(string dbConfigName)
        {
            this.dbConfigName = dbConfigName;
        }

        ....................
}

3、在BaseBLL里面的Init函数举行调用设置处理

        /// <summary>
        /// 参数赋值后,初始化相关对象
        /// </summary>
        /// <param name="bllFullName">BLL业务类的全名(子类必须实现),子类构造函数传入this.GetType().FullName</param>
        /// <param name="dalAssemblyName">数据访问层程序集的清单文件的文件名,不包括其扩展名。设置为NULL或默认为Assembly.GetExecutingAssembly().GetName().Name</param>
        /// <param name="bllPrefix">BLL命名空间的前缀(BLL.)</param>
        /// <param name="dbConfigName">数据库配置项名称</param>
        protected void Init(string bllFullName, string dalAssemblyName = null, string bllPrefix = "BLL.")
        {
            .............
            baseDal.SetDbConfigName(dbConfigName); //设置数据库配置项名称
        }

4、在具体BLL层的工作类进行早先化处理。

    /// <summary>
    /// 政策法规公告动态
    /// </summary>
    public class Information : BaseBLL<InformationInfo>
    {
        public Information() : base()
        {
            base.Init(this.GetType().FullName, System.Reflection.Assembly.GetExecutingAssembly().GetName().Name, "BLL.", "annotherConfig" );
        }

诸如此类设置后,大家现实调用的代码不变,不过指定工作的数据库访问已经选取了一定的布局项名称了,假设计划项不存在,那么依旧会获取默认的配置项进行处理了。

透过那样的贯彻步骤,大家就能促成在一个事务种类里头,分拆分裂的数据库,举办统一管理,而且又不会增加额外的调用难度,对于我们不少作业表,那种框架的处理格局,应该是科学的。

 

相关文章