最近写项目一直在用EF , 跨库能力极强. 很喜欢.
但是不能动态切换数据库, 最近搞了一个配置中心的功能, 把连接字符串放到配置中心中单独配置管理.
但是EF默认是放到Web.config中的. 就算自己拼装出了连接字符串也会因为没有 providerName=“System.Data.SqlClient” 而失败.
经过再三研究, 今天研究了一下午终于搞定了.
关键是要重载 DbContext 的一个构造函数
public partial class DatacenterContext: DbContext
{
static DatacenterContext()
{
//DbConfiguration.SetConfiguration()
Database.SetInitializer< DatacenterContext>(null);
}
public DatacenterContext(DbConnection conn)
: base(conn, true)
{
//这个方法是用来实现切换不同库的主方法.本身EF就提供的.
}
}
数据库连接工厂, 的作用是在EF初始化之前先实例化一个新的数据库连接. 然后用它实例化 EF 的 DbContext
public static class DBContextFactory
{
static string reportDBType = MK.Base.CenterConfig.GetConfig("数据库类型");
static string dbip = MK.Base.CenterConfig.GetConfig("数据库IP地址");
static string dbport = MK.Base.CenterConfig.GetConfig("数据库端口");
static string dbuser = MK.Base.CenterConfig.GetConfig("数据库用户名");
static string dbpassword = MK.Base.CenterConfig.GetConfig("数据库密码");
static string dbname = MK.Base.CenterConfig.GetConfig("数据库名或(Orcale)服务名");
/// <summary>
/// 根据配置取得数据库连接上下文
/// </summary>
/// <returns></returns>
public static DbContext GetReportDataDbContext()
{
var conn=GetDbConnection(reportDBType,dbip, dbuser, dbpassword, dbname, dbport);
return new DatacenterContext(conn);
}
private IDbConnection GetDbConnection(string reportDBType,string dbip, string dbuser, string dbpassword, string dbname, string dbport)
{
//string reportDBType = MK.Base.CenterConfig.GetConfig("数据库类型");
//string dbip = MK.Base.CenterConfig.GetConfig("数据库IP地址");
//string dbport = MK.Base.CenterConfig.GetConfig("数据库端口");
//string dbuser = MK.Base.CenterConfig.GetConfig("数据库用户名");
//string dbpassword = MK.Base.CenterConfig.GetConfig("数据库密码");
//string dbname = MK.Base.CenterConfig.GetConfig("数据库名或(Orcale)服务名");
if (reportDBType == "MySql")
{
var sqlbulider = new MySqlConnectionStringBuilder();
sqlbulider.Server = dbip;
sqlbulider.UserID = dbuser;
sqlbulider.Password = dbpassword;
sqlbulider.Database = dbname;
sqlbulider.Port = string.IsNullOrEmpty(dbport)?3306: uint.Parse(dbport);
//sqlbulider.AllowZeroDateTime = true;
//sqlbulider.ConvertZeroDateTime = true;
//sqlbulider.IntegratedSecurity = true;
return new MySqlConnection(sqlbulider.ConnectionString);
}
else if (reportDBType == "SqlServer")
{
//var connectstring = string.Format("Data Source={0},{4};Initial Catalog={3};Persist Security Info=True;User ID={1};Password={2};", dbip, dbuser, dbpassword, dbname, dbport);
var sqlbulider = new SqlConnectionStringBuilder();
sqlbulider.DataSource = dbip + (string.IsNullOrEmpty(dbport)?"":","+dbport);
sqlbulider.UserID = dbuser;
sqlbulider.Password = dbpassword;
sqlbulider.InitialCatalog = dbname;
sqlbulider.PersistSecurityInfo = true;
//sqlbulider.IntegratedSecurity = true;
return new SqlConnection(sqlbulider.ConnectionString);
}
else if (reportDBType == "Oracle")
{
//connectstring = string.Format("Data Source={0},{4};Initial Catalog={3};Persist Security Info=True;User ID={1};Password={2};", dbip, dbuser, dbpassword, dbname, dbport);
//var sqlbulider = new OracleConnectionStringBuilder();
//sqlbulider.DataSource = dbip + "," + uint.Parse(dbport);
//sqlbulider.UserID = dbuser;
//sqlbulider.Password = dbpassword;
//sqlbulider.s
sqlbulider.UserID = dbname;
sqlbulider.s = dbname;
//sqlbulider.PersistSecurityInfo = true;
var connstring = "Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST={dbip}) (PORT={dbport})))(CONNECT_DATA=(SERVICE_NAME={dbname})));User Id={dbuser}; Password={dbpassword}";
connstring = connstring.Replace("{dbip}", dbip)
.Replace("{dbport}", (string.IsNullOrEmpty(dbport) ? "1521" : dbport))
.Replace("{dbname}", dbname)
.Replace("{dbuser}", dbuser)
.Replace("{dbpassword}", dbpassword);
return new OracleConnection(connstring);
}else
{
throw new Exception("暂不支持的数据库类型");
}
}
}
使用的时候是下面这样的
var context = DBContextFactory.GetReportDataDbContext();