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

时间: 2024-10-11 03:27:42

EF6 Create Different DataContext on runtime(运行时改变连接字符串)的相关文章

iOS开发——高级特性&amp;Runtime运行时特性详解

Runtime运行时特性详解 本文详细整理了 Cocoa 的 Runtime 系统的知识,它使得 Objective-C 如虎添翼,具备了灵活的动态特性,使这门古老的语言焕发生机.主要内容如下: 引言 简介 与Runtime交互 Runtime术语 消息 动态方法解析 消息转发 健壮的实例变量(Non Fragile ivars) Objective-C Associated Objects Method Swizzling 总结 引言 曾经觉得Objc特别方便上手,面对着 Cocoa 中大量

Runtime 运行时之一:消息传递

什么是Runtime? Runtime顾名思义即为运行时.就是系统运行时候的一些机制,它提供了一些使得对象之间能够传递消息的重要函数,其中最主要的就是消息机制了.相较于C语言而言,C语言使用的是“静态绑定”,函数的调用在编译期就能知道运行期所需要调用的函数了,编译完成之后就按照顺序执行(面向过程就是这么任性).而OC使用的是“动态绑定”特性,也就是说编译器在编译期的时候无法决定运行期调用哪个函数,也就是说在编译阶段,OC可以调用任何函数,即使该函数未实现,但只要声明过就不会报错,而C语言则会报错

runtime 运行时机制 完全解读

runtime 运行时机制 完全解读 目录[-] import import 我们前面已经讲过一篇runtime 原理,现在这篇文章主要介绍的是runtime是什么以及怎么用!希望对读者有所帮助! 首先,第一个问题, 1>runtime实现的机制是什么,怎么用,一般用于干嘛? 这个问题我就不跟大家绕弯子了,直接告诉大家, runtime是一套比较底层的纯C语言API, 属于1个C语言库, 包含了很多底层的C语言API. 在我们平时编写的OC代码中, 程序运行过程时, 其实最终都是转成了runti

?runtime 运行时机制

?runtime 运行时机制 完全解读 摘要 在最开始听到runtime的时候,我是感到恐惧的,多么高大上的东西啊!!!后来,开始在网上查一些资料,可是就是只有那么几篇,看了好久,还不知所云,所以就更加恐惧了!!!!后来经过查看documents 以及一些国外大牛的blogs,终于对runtime有了更深刻的了解!于是就想写下这些东西,希望对读者们有帮助…… runtime 运行时机制 详细解读 目录[-] import import 我们前面已经讲过一篇runtime 原理,现在这篇文章主要介

iOS的runtime运行时机制

本文转自http://www.cnblogs.com/guoxiao/p/3583432.html 最近一直在研究runtime运行时机制的问题,我想可能也有很多人不太清楚这个问题吧?在这里跟大家沟通分享下我对与runtime机制的理解. 要理解runtime,首先我们要了解类和对象的内部结构,下面将首先介绍下OC中类与对象的结构层次. 一.首先,从 runtime.h头文件中找到对 class 与 object 的定义 /// An opaque type that represents an

runtime运行时机制 (一)

#import <objc/runtime.h> // 通过运行时来遍历每个属性 unsigned int count; //class_copyIvarList 获取所有属性数组 Ivar *varList = class_copyIvarList([UITextField class],&count); for (NSInteger i = 0; i < count; i++) { Ivar var = varList[i]; //遍历所有属性的名字 NSLog(@"

Objective-C Runtime 运行时之二:成员变量与属性

类型编码(Type Encoding) 作为对Runtime的补充,编译器将每个方法的返回值和参数类型编码为一个字符串,并将其与方法的selector关联在一起.这种编码方案在其它情况下也是非常有用的,因此我们可以使用@encode编译器指令来获取它.当给定一个类型时,@encode返回这个类型的字符串编码.这些类型可以是诸如int.指针这样的基本类型,也可以是结构体.类等类型.事实上,任何可以作为sizeof()操作参数的类型都可以用于@encode(). 在Objective-C Runti

Objective-C Runtime 运行时之三:方法与消息

基础数据类型 SEL SEL又叫选择器,是表示一个方法的selector的指针,其定义如下: typedef struct objc_selector *SEL; objc_selector结构体的详细定义没有在<objc/runtime.h>头文件中找到.方法的selector用于表示运行时方法的名字.Objective-C在编译时,会依据每一个方法的名字.参数序列,生成一个唯一的整型标识(Int类型的地址),这个标识就是SEL.如下代码所示: 1 2 SEL sel1 = @selecto

iOS开发之runtime运行时机制

最近参加三次面试都有被问到runtime,也不知道面试官们自己懂不懂,反正就喜欢问,似乎就想把我唬住,来显示自己的对OC底层知识的理解很牛逼似的.(我现在开始看面试题,发现他们都喜欢问面试题的问题,我算明白了,都是应试教育惹的祸,大概他们以前没什么实际的app经验,所以准备了很多面试题,而我真的是能写app,先干活再找方法的人,面试不多,没什么面试经验,看来要开始碰壁多次才能掌握中国式面试).因为不太懂runtime我就只能支支吾吾的说点零碎.我真的好几次努力想看一看runtime的知识,因为知