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();
}转载请注明出处。