zoukankan      html  css  js  c++  java
  • 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) { }
    }
    }

    参考

    https://stackoverflow.com/questions/18272708/how-to-force-dbcontext-refresh-connection-string-from-config

    https://stackoverflow.com/questions/15504465/entityframework-code-first-custom-connection-string-and-migrations/16133150#16133150

    https://github.com/mono/entityframework/blob/master/src/EntityFramework/Infrastructure/SqlConnectionFactory.cs

    作者:旭东
    出处:http://www.cnblogs.com/HQFZ
    关于作者:专注于微软平台项目架构、管理和企业解决方案。现主要从事WinForm、ASP.NET、WPF、WCF、等方面的项目开发、架构、管理。如有问题或建议,请不吝指教!
    本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。如有问题,可以联系我,非常感谢。
    如果您该文觉得不错或者对你有帮助,请点下推荐,让更多的朋友看到,谢谢!

  • 相关阅读:
    webpack打包踩坑记录
    node笔记
    你真的会Xilinx FPGA的复位吗?
    Verilog 99题之001-009
    数字电路基础
    跨时钟域处理
    时序逻辑电路基础
    FPGA&ASIC基本开发流程
    关于FPGA的一些小见解
    基于FPGA的I2C读写EEPROM
  • 原文地址:https://www.cnblogs.com/HQFZ/p/4112956.html
Copyright © 2011-2022 走看看