Winform开发框架中贯彻强数据库类型切换以及分拆数据库的支持。Winform开发框架中实现多数据库类型切换以及分拆数据库的支持。

于无数下系统间,虽然一般下同样种数据库运行,但是出于各种状况的需要,可能工作系统会配备在不同品类的数据库及,如果开之系统能够非常有利支持多数据库的切换,那得为咱减少过多闷,同时提高系统的适应性和强壮型。还有平等种植状况,由于业务数据库的随地膨胀或者好数据库的切割隔离,有时候为会见管不同的事务数据库进行分拆,如权限提供数据库,客户关系管理数据库,工作流程数据库,企业营运数据库等等,因此在一个系中,同时采取2独或以上的数据库的图景也是一些。针对当下半种植情况,本文介绍于自身之Winform开发框架(也利用本人的其余框架),如何具体处理这简单个问题的。

于众动体系里,虽然一般以相同种植数据库运行,但是由各种情形的要,可能工作系统会部署于不同品类的数据库及,如果出之系会生有益于支持多数据库的切换,那可为咱减过多憋,同时提高系统的适应性和强壮型。还有雷同种植状况,由于业务数据库的无休止膨胀或者好数据库的切割隔离,有时候为会见把不同之事体数据库进行分拆,如权限提供数据库,客户关系管理数据库,工作流程数据库,企业营运数据库等等,因此在一个体系间,同时以2个或以上之数据库的景象吧是部分。针对当下简单种植状态,本文介绍于自己的Winform开发框架(也采取自己之外框架),如何切实处理及时有限只问题之。
当自家的各种开销框架中,底层都是动同一栽数据库的走访方式,就是采取了Enterprise
Library的数据库访问模块,这个是微软始发源之企业应用模块,里面各种以模块,都堪称是出的特等实践。当然利用中的数据库访问模块,是十分广阔的,这个数据库访问模块,可以经配备的方支持多数据库的生成。因此做到自的Winform开发框架中,也不行轻实现这种多数据库的措施处理。
Winform开发框架,常见的道岔模式,可以分为UI层、BLL层、DAL层、IDAL层、Entity层、公用类库层等等,B/S的Web开发框架为是供类似之架模式,它们只是Web界面层有所不同,这样即便深受咱们提供了一个统一性的付出模式,使得开发起来更为便捷,统一性更好。框架界面层以下的架构设计图如下所示。

以本人的各种开销框架内,底层都是运用同样种数据库的访方式,就是行使了Enterprise
Library的数据库访问模块,这个是微软起源之企业应用模块,里面各种应用模块,都堪称是付出之极品实践。当然利用内部的数据库访问模块,是甚普遍的,这个数据库访问模块,可以由此部署的计支持多数据库的生成。因此做及自我的Winform开发框架内,也酷轻实现这种多数据库的不二法门处理。

lovebet爱博体育官网 1

Winform开发框架,常见的道岔模式,可以分成UI层、BLL层、DAL层、IDAL层、Entity层、公用类库层等等,B/S的Web开发框架为是提供类似之架构模式,它们只是Web界面层有所不同,这样即使为我们提供了一个统一性的支出模式,使得开发起来越高效,统一性更好。框架界面层以下的架构设计图如下所示。

1、支持多数据库的装置

1)数据库访问基类的问询
为了介绍支持多数据库的模式,我们要事先来打探下所有框架的层次结构。
AbstractBaseDAL是空虚了有着数据库实现的超级基类。
BaseDALSQL是对准SqlServer数据库有调整基类(很粗的调动)。
BaseDALSQLite是针对性Sqlite数据库的一些调整基类(很粗之调整)。
BaseDALMySql是针对MySqlite数据库的有些调整基类(很有些的调整)。
BaseDALAccess是本着Access数据库的有调整基类(很有些的调)。
IBaseDAL是兼具基础数据库访问类的接口。
多少看接口实现交汇(如Customer)和接口定义层(ICustomer)一样,都起一个基类,如因SqlServer实现之基类为BaseDALSQL,这个基于SqlServer的多寡访问基类,它吧是后续自一个最佳基类(大多数底实现在此间)AbstractBaseDAL。他们中的存续关系如下所示

lovebet爱博体育官网 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配置起,就得组织对应之数据库访问对象了。两者合就可是获取到处理目标,并成功拍卖数据库的走访。

lovebet爱博体育官网 3

lovebet爱博体育官网 4

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" );
    }

这么设置后,我们现实调用的代码不换,但是指定工作的数据库访问已经采取了一定的配备起名称了,如果安排起非设有,那么还是会获得默认的部署起进行拍卖了。

透过如此的贯彻步骤,我们尽管可知促成以一个业务系统内,分拆不同之数据库,进行统一保管,而且以未见面追加额外的调用难度,对于咱们多工作表,这种框架的处理方式
,应该是不易的。

1、支持多数据库的安

1)数据库访问基类的打听

以介绍支持多数据库的模式,我们用先来了解下整框架的层次结构。

AbstractBaseDAL是空洞了颇具数据库实现之极品基类。

BaseDALSQL是针对性SqlServer数据库有调整基类(很有点的调动)。

BaseDALSQLite是对准Sqlite数据库的一对调整基类(很粗之调动)。

BaseDALMySql是针对性MySqlite数据库的部分调整基类(很有点的调动)。

BaseDALAccess是对准Access数据库的有调整基类(很有点之调动)。

IBaseDAL是颇具基础数据库访问类的接口。

数量看接口实现交汇(如Customer)和接口定义层(ICustomer)一样,都生一个基类,如基于SqlServer实现的基类为BaseDALSQL,这个基于SqlServer的多少看基类,它吗是持续自一个顶尖基类(大多数之落实以这边)AbstractBaseDAL。他们之间的延续关系如下所示

lovebet爱博体育官网 5

一旦我们才在项目工的觊觎里看到,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" );
        }

如此设置后,我们切实调用的代码不更换,但是指定业务的数据库访问已经用了特定的布起名称了,如果安排起不存在,那么还是会沾默认的布局起进行处理了。

由此如此的落实步骤,我们即便能够实现在一个事情体系里面,分拆不同之数据库,进行联合保管,而且以未见面增多额外的调用难度,对于咱们广大业务表,这种框架的处理方式
,应该是不错的。

 

相关文章