在使用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使用我們的連接字串,以達到保護數據庫的目的。