在实际工作中,我们可能会遇到在同一个程序中链接多套结构相同的数据库的情况,虽然我认为这并不是好的设计,但是这也许并不在你的控制之中,比如你的公司有两个客户,用同一套系统,如果不把他们的库分开,可能会带来功能设计上的困难和数据的混乱,所以产生了两套数据库,结构一模一样,只是数据不同。现在你要设计一个对外接口给别的程序使用,程序有可能会请求A库的数据,也有可能会请求B库的数据,这如何去做呢?
显而易见,使用不同的连接字符串就OK了,但要让代码更工整一些,就得稍微花点点心思。下面是我写的DEMO的截图:
首先在本地的SQL Express中创建几个简单的用于测试的数据库,再创建一张简单的表,然后随便插入两条简单的记录:
create database TestDb1 go use TestDb1 go create table TB_USER ( USER_ID int identity, USER_NAME nvarchar(20) not null, REAL_NAME nvarchar(25) not null, DESCRIPTIONS nvarchar(400) null, ) go insert into TB_USER(USER_NAME, REAL_NAME, DESCRIPTIONS) values('jgg', '蒋国纲', '码农') insert into TB_USER(USER_NAME, REAL_NAME) values('zs', '张三') go create database TestDb2 go use TestDb2 go create table TB_USER ( USER_ID int identity, USER_NAME nvarchar(20) not null, REAL_NAME nvarchar(25) not null, DESCRIPTIONS nvarchar(400) null, ) go insert into TB_USER(USER_NAME, REAL_NAME, DESCRIPTIONS) values('us', 'Uncle Sam', '美国佬') insert into TB_USER(USER_NAME, REAL_NAME) values('jp', '小日本') go create database TestDb3 go use TestDb3 go create table TB_USER ( USER_ID int identity, USER_NAME nvarchar(20) not null, REAL_NAME nvarchar(25) not null, DESCRIPTIONS nvarchar(400) null, ) go insert into TB_USER(USER_NAME, REAL_NAME, DESCRIPTIONS) values('abcd', 'efg', 'hijklmn') insert into TB_USER(USER_NAME, REAL_NAME, DESCRIPTIONS) values('opq', 'rst', 'uvwxyz') go
然后配置一下你的App.Config:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <connectionStrings> <add name="TestDb1" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=TestDb1;Integrated Security=True" providerName="System.Data.SqlClient"/> <add name="TestDb2" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=TestDb2;Integrated Security=True" providerName="System.Data.SqlClient"/> <add name="TestDb3" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=TestDb3;Integrated Security=True" providerName="System.Data.SqlClient" /> </connectionStrings> <!--省略好多内容--> </configuration>
然后做一个工具类,帮助你生成链接到不同的库的DataContext对象(这么一来你的代码也就整齐多了):
using System; using System.Data.Linq; using System.Diagnostics; using System.Configuration; namespace MultiDbmsConnectionsDemo { public static class DataContextFactory { public static DataContext Create(Type typeDataContext, string strDbName) { Debug.Assert(typeDataContext.IsSubclassOf(typeof(DataContext))); string strDbConn; try { strDbConn = ConfigurationManager.ConnectionStrings[strDbName].ConnectionString; } catch (Exception) { return (DataContext) Activator.CreateInstance(typeDataContext); } return (DataContext)Activator.CreateInstance(typeDataContext, strDbConn); } } }
其中使用了Activator,Activator会根据传入的Type来创建对应的DataContext实例,当然你也可以使用泛型;另外如果传入的连接字符串的名称不存在于配置文件中的话就使用默认的链接,即创建DataContext的时候不带参数。
这是例子:
//一般的做法是: //LinqUserDataContext db = new LinqUserDataContext(); //而现在是: LinqUserDataContext db = (LinqUserDataContext) DataContextFactory.Create(typeof(LinqUserDataContext), comboDbmsChoosing.Text);
小技巧,希望能够让你的代码better一些。
完整代码:下载
代码中使用了一个LINQ to SQL的帮助类,具体可以参考我另一篇blog:LINQ to SQL使用教程