EF下使用自定义的connectionString避免数据库密码泄露
在使用EF框架时,缺省情况下数据库访问字串是明码存放在app.config或web.config中的,相当于让数据库裸奔。
实际上EF在创建数据实体时,可以指定连接字串,取代在app.config中读取连接字串的方式,但缺省下并不提供(大硬是不是缺根筋啊)
分析数据实体的构造函数可以看到:
public UserManageEntities(): base("name=UserManageEntities") { }
可见实体是通过基类DbContext来创建的,而基类DbContext的构造函数如下:
// // 摘要: // 可以将给定字符串用作将连接到的数据库的名称或连接字符串来构造一个新的上下文实例。请参见有关这如何用于创建连接的类备注。 // // 参数: // nameOrConnectionString: // 数据库名称或连接字符串。 [SuppressMessage("Microsoft.Reliability", "CA2000:Dispose objects before losing scope")] [SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")] public DbContext(string nameOrConnectionString);
Name Or ConnectionString啊大哥,为什么EF实体的构造函数就不能缺省提供一个connectionString的重载呢?
没办法,只好自己动手了。需要两步:
1. 构造EF的连接字串
这里可以采用EntityConnectionStringBuilder来生成
EntityConnectionStringBuilder ecb = new EntityConnectionStringBuilder(); ecb.Metadata = "res://*/UserManage.csdl|res://*/UserManage.ssdl|res://*/UserManage.msl"; ecb.Provider = "System.Data.SqlClient"; ecb.ProviderConnectionString = "data source=(localdb)\\MSSQLLocalDB;initial catalog=UserManage;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework";
然后在通过ecb.ConnectionString可以获取到EF的连接字串。
其中MetaData、ProviderConnectionString可以从EF自动生成的连接字串中分析参考拿来用
2.增加实体的的构造函数,让其接受ecb.ConnectionString参数
原构造函数:
public UserManageEntities(): base("name=UserManageEntities") { }
这个构造函数的意思是将app.config(或web.config)中,name为UserManageEntities的连接字串取出做为构造函数的参数。
这里增加一个构造函数的重载,接收ecb.ConnectionString参数
public UserManageEntities(string connString): base(connString) { }
这样,我们在生成实例时,调用我们的新构造函数就可以了:
UserManageEntities db = new UserManageEntities(ecb.ConnectionString);
通过这样处理,我们可以将数据库访问密码封装在程序中,动态生成连接字串,并让EF使用我们的连接字串,以达到保护数据库的目的。