Support for switching multiple database types and splitting databases in the Winform development framework

Source: Internet
Author: User
Tags connectionstrings

In many application systems, although a database is generally used for running, the business system may be deployed on different types of databases due to various situations, if the developed system can easily support switching between multiple databases, it can reduce a lot of troubles and improve the adaptability and robustness of the system. In another case, due to the constant expansion of the business database or the convenience of database cutting and isolation, different business databases are sometimes split, such as the database providing permissions and the customer relationship management database, workflow databases, Enterprise Operation databases, and so on. Therefore, two or more databases are used in one system. This article describes how to solve these two problems in my Winform development framework (also using my other frameworks.

In my various development frameworks, the bottom layer adopts the same database access mode, that is, the database access module of Enterprise Library. This is an open-source Enterprise application module of Microsoft, the various application modules are the best practices for development. Of course, the database access module is widely used. This database access module supports various database changes through configuration. Therefore, it is easy to implement this multi-database processing method when integrated into my Winform development framework.

The Winform development framework and common layered modes can be divided into the UI Layer, BLL layer, DAL layer, IDAL layer, Entity layer, and public class library layer, the B/S Web development framework also provides similar architecture models. They only differ in the Web interface layer. This provides us with a uniform development model, making development more efficient, uniformity is better. The architecture diagram below the framework interface layer is as follows.

1. Supports multi-database settings

1) Understanding of Database Access Base classes

To introduce the modes that support multiple databases, we need to first understand the hierarchy of the entire framework.

AbstractBaseDAL is a super base class that abstracts all database implementations.

BaseDALSQL is used to adjust the base class for some SqlServer databases (small adjustments ).

BaseDALSQLite is a small adjustment base class for the Sqlite database ).

BaseDALMySql is a small adjustment base class for the MySqlite database ).

BaseDALAccess is a small adjustment of the base class for the Access database ).

IBaseDAL is an interface for all basic database Metadata classes.

The data access interface Implementation Layer (such as Customer) and interface definition layer (ICustomer) all have a base class. For example, the base class implemented based on SqlServer is BaseDALSQL, this SqlServer-based Data Access Base class also inherits from a super base class (most implementations here) AbstractBaseDAL. The inheritance relationships between them are as follows:

As we can see in the project diagram just now, the class libraries BaseDALSQL, IBaseDAL, and AbstractBaseDAL have great versatility. To reduce the maintenance problems caused by Replication in different projects, therefore, we extract all these frequently used base classes or interfaces into an independent class library to distinguish them from common DotNET public class library names (WHC. framework. commons), we name it WHC. framework. controlUtil.

2) multi-database code implementation

To achieve multi-database support, we need to read the relevant configuration in the configuration file to see the specific structure of the database, and then initialize different assembly classes, in this way, you can call different database types.

The implementation code in the BaseBLL Init function is as follows.

# Region construct the corresponding DAL layer AppConfig config = new AppConfig (); string dbType = config according to different database types. 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); // Replace intermediate BLL. is DAL ., is the full name of the DAL class baseDal = Reflect <IBaseDAL <T>. create (this. dalName, dalAssemblyName); // construct the object class of the corresponding DAL data access layer

When calling a specific business object, we don't know which database processing class it calls for processing. We only need to call its basic interface, the following is part of the call code at the interface layer.

// Delete the associated attachment 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 );}}}

In the specific configuration file, we can configure the relevant database as needed.

According to the Enterprise Library configuration, if <dataConfiguration defaultDatabase = "sqlserver"> is created, the sqlServer node is obtained, and the code parses the ComponentDbType configuration item, you can construct the corresponding database access object. When the two are combined, the processing object can be correctly obtained and the database access can be processed successfully.

<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> <etettings> <! -- Component Database Type: access, sqlserver, sqlite, etc. --> <add key = "ComponentDbType" value ="Sqlserver"/>

 

2. Support settings for splitting different databases

As described above, only one database can be accessed at a time. Therefore, the following code is used by default to construct database access objects.

Database db = DatabaseFactory.CreateDatabase();

In this way, only the database set by defaultDatabase will be obtained each time for construction. If we support access to multiple databases in one system at the same time, what should we do.

In the Framework's base class AbstractBaseDAL, we encapsulate the code used to construct the database.

/// <Summary> /// generate a Database object based on the configuration name of the 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 ;}

Each DAL layer inherits from AbstractBaseDAL, so that you can use different databases by specifying dbConfigName In the DAL layer.

However, this problem occurs. If we have five DAL layers of different types of databases (SqlServer, Oracle, Mysql, Access, Sqlite, therefore, it is inconvenient to write some code for the Implementation classes of each DAL layer. Can you abstract the code to the BLL layer so that only one configuration can be written? This is a good idea, let's take a look at how to implement it.

1) define interfaces at the IBaseDAL Layer

/// <Summary> /// interface of the data access layer /// </summary> public interface IBaseDAL <T> where T: baseEntity {// <summary> // set the database configuration item name /// </summary> /// <param name = "dbConfigName"> database configuration item name </param> void SetDbConfigName (string dbConfigName );
.............}

2. Add the default implementation code in AbstractBaseDAL.

/// <Summary> // super base class of the data access layer. The data access base classes of all databases are inherited from this super base class, including Oracle, SqlServer, Sqlite, MySql, Access, etc. // </summary> public abstract class implements actbasedal <T> where T: BaseEntity, new () {// <summary> /// set the database configuration item name /// </summary> /// <param name = "dbConfigName"> database configuration item name </param> public virtual void SetDbConfigName (string dbConfigName) {this. dbConfigName = dbConfigName ;}
....................}

3. call and set the Init function in BaseBLL.

/// <Summary> /// after the parameter value is assigned, initialize the relevant object /// </summary> /// <param name = "bllFullName"> full name of The BLL service class (required by the subclass). The subclass constructor passes in this. getType (). fullName </param> // <param name = "dalAssemblyName"> name of the configuration file of the data access layer assembly, excluding its extension. Set to NULL or the default value is Assembly. getExecutingAssembly (). getName (). name </param> /// <param name = "bllPrefix"> prefix of the BLL namespace (BLL .) </param> /// <param name = "dbConfigName"> database configuration item name </param> protected void Init (string bllFullName, string dalAssemblyName = null, string bllPrefix = "BLL. "){............. baseDal. setDbConfigName (dbConfigName); // set the database configuration item name}

4. initialize the business class at the specific BLL layer.

/// <Summary> // policy and regulation announcement dynamics // </summary> public class Information: BaseBLL <InformationInfo> {public Information (): base () {base. init (this. getType (). fullName, System. reflection. assembly. getExecutingAssembly (). getName (). name, "BLL. "," annotherConfig ");}

After this setting, the code of the specific call remains unchanged, but the specific configuration item name is used for database access of the specified business. If the configuration item does not exist, the default configuration items will be obtained for processing.

Through this implementation step, we can implement a business system, split different databases for unified management, without increasing the call difficulty. For many of our business tables, the processing method of this framework should be good.

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.