EntityFramework自动将数据库映射到Model,同时会生成相应的连接字符串,如下图。
生成之后,我们看到自动生成的DBDemoEntities的类,只有一个默认的无参的构造函数,如下图
这在一般情况下是OK的,因为只我们在App.config或者Web.config配置了这个连接串即可。如下图。
但是当我们希望自己传入连接字符串时,就无能为力了。那我们怎么办?我们看到DBDemoEntities的构造函数是继承自DbContext的,而DbContext是支持含参构造函数的,如下图
DbContext中的参数是nameOrConnectionString,从名字上可以直观的看到该参数可以是一个name,也可以是一个连接字符串,所以如果我们有办法将连接字符串传到这里来构造就可以了。简单的就是在DBDemoEntities加一个含参的构造函数,代码如下
//------------------------------------------------------------------------------ // <auto-generated> // 此代码已从模板生成。 // // 手动更改此文件可能导致应用程序出现意外的行为。 // 如果重新生成代码,将覆盖对此文件的手动更改。 // </auto-generated> //------------------------------------------------------------------------------ namespace DefineModel { using System; using System.Data.Entity; using System.Data.Entity.Infrastructure; public partial class DBDemoEntities : DbContext { public DBDemoEntities(string connectStr) : base(connectStr) { } public DBDemoEntities() : base("name=DBDemoEntities") { } protected override void OnModelCreating(DbModelBuilder modelBuilder) { throw new UnintentionalCodeFirstException(); } public virtual DbSet<TUser> TUser { get; set; } } }这个代码理论上是没有问题的,但是我们看到这个类的头部有说明了,如果手写代码,再生成模型时会被覆盖掉,这对我们来说简单就是一个恶梦。这意味着每次生成都需要重新加一个带参的构造函数进去。那有没有其他办法呢?
有的!
我们只需要加一个DBDemoEntities部分类的文件到该模型的项目中,然后实现含参构造函数,如下图
接下来我们只需要构造一个连接字符串即可。为了方便构建,我们直接将配置文件中的connectionString复制出来,然后将里面的“""替换成",然后将服务端ip、数据库名称、用户名和密码替换成变量即可。为了方便,我们封装成了一个函数,代码如下。
private static string FetchConnectStr(string dbName, string ip, string userId, string password) { string connectStr = "metadata=res://*/DemoModel.csdl|res://*/DemoModel.ssdl|res://*/DemoModel.msl;provider=System.Data.SqlClient;provider connection string="data source=" + ip + ";initial catalog=" + dbName + ";persist security info=True;user id=" + userId + ";password=" + password + ";MultipleActiveResultSets=True;App=EntityFramework""; return connectStr; }我们新建一个控制台项目来测试,代码如下
static void Main(string[] args) { string connectStr = FetchConnectStr("数据库名称", "IP", "用户名", "密码"); var entitties = new DBDemoEntities(); var list = entitties.TUser.Select(t => t); foreach (var item in list) { Console.WriteLine(item.u_nickname); } Console.ReadLine(); }
转载请注明出处。