EF6 Create Different DataContext on runtime(运行时改变连接字符串)
引言
在使用EF时,有时我们需要在程序运行过程中动态更改EF的连接字符串,但不幸的时EF是否对
ConfigurationManager.RefreshSection("xxx")
这行代码的影响不大,我没去深究,还请大侠指点。(本人猜测,EF内部实现没有订阅RefreshSection的事件去做相应的更换连接字符串的处理),如果确实想用该方法通过修改配置文件来实现动态更换连接字符串,那最保守的做法再加上个重启应用程序的方法。(确保EF能重新读到新的配置信息。)
这个时候就需要我们在DataContext新建时使用指定DBConnection来解决该问题,Demo如下:
APP.CONFIG (Uses EF 6)
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" /> </configSections> <startup> <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" /> </startup> <entityFramework> <defaultConnectionFactory type="System.Data.Entity.Infrastructure.SqlConnectionFactory, EntityFramework"> <parameters> <parameter value="Data Source=localhost; Integrated Security=True; MultipleActiveResultSets=True" /> </parameters> </defaultConnectionFactory> </entityFramework> </configuration>
the code to make as small as possible for Demo:
using System; using System.Data.Common; using System.Data.Entity; using System.Data.Entity.Infrastructure; using System.Data.Entity.Migrations; namespace Ef6Test { public class Program { public static void Main(string[] args) { Database.SetInitializer(new MigrateDatabaseToLatestVersion<Ef6Ctx, Ef6MigConf>()); WhichDb.DbName = "HACKDB1"; var sqlConn = GetSqlConn4DBName(WhichDb.DbName); var context = new Ef6Ctx(sqlConn); context.Database.Initialize(true); AddJunk(context); //sqlConn.Close(); //?? whatever other considerations, dispose of context etc... Database.SetInitializer(new MigrateDatabaseToLatestVersion<Ef6Ctx, Ef6MigConf>()); // yes its default again reset this !!!! WhichDb.DbName = "HACKDB2"; var sqlConn2 = GetSqlConn4DBName(WhichDb.DbName); var context2 = new Ef6Ctx(sqlConn2); context2.Database.Initialize(true); AddJunk(context2); } public static class WhichDb { // used during migration to know which connection to build public static string DbName { get; set; } } private static void AddJunk(DbContext context) { var poco = new pocotest(); poco.f1 = DateTime.Now.ToString(); // poco.f2 = "Did somebody step on a duck?"; //comment in for second run context.Set<pocotest>().Add(poco); context.SaveChanges(); } public static DbConnection GetSqlConn4DBName(string dbName) { var sqlConnFact = new SqlConnectionFactory( "Data Source=localhost; Integrated Security=True; MultipleActiveResultSets=True"); var sqlConn = sqlConnFact.CreateConnection(dbName); return sqlConn; } } public class MigrationsContextFactory : IDbContextFactory<Ef6Ctx> { public Ef6Ctx Create() { var sqlConn = Program.GetSqlConn4DBName(Program.WhichDb.DbName); // NASTY but it works return new Ef6Ctx(sqlConn); } } public class Ef6MigConf : DbMigrationsConfiguration<Ef6Ctx> { public Ef6MigConf() { AutomaticMigrationsEnabled = true; AutomaticMigrationDataLossAllowed = true; } } public class pocotest { public int Id { get; set; } public string f1 { get; set; } // public string f2 { get; set; } // comment in for second run } public class Ef6Ctx : DbContext { public DbSet<pocotest> poco1s { get; set; } public Ef6Ctx(DbConnection dbConn) : base(dbConn, true) { } } }
参考
作者:旭东
出处:http://www.cnblogs.com/HQFZ
关于作者:专注于微软平台项目架构、管理和企业解决方案。现主要从事WinForm、ASP.NET、WPF、WCF、等方面的项目开发、架构、管理。如有问题或建议,请不吝指教!
本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。如有问题,可以联系我,非常感谢。
如果您该文觉得不错或者对你有帮助,请点下推荐,让更多的朋友看到,谢谢!