Entity Framework Code First 學習日記(4)


因為家里有點事,就耽誤了隨后的更新。很抱歉讓大家等了好幾天,我就不再耽誤時間了,讓我們馬上切入正題。

上次日記中我跟大家提前透露了這篇日記將介紹一些與DbContext有關的內容。廖羽同學問了兩個問題,他問的問題正好是我這次要講的,我們怎么配置DbContext的子類訪問的數據庫的位置。

我相信大家最經常使用的數據庫位置的配置方式就是配置文件了,也就是通過App.Config 或Web.Config來配置要訪問的數據庫。

Entity Framework Code First同樣也可以通過配置文件來配置要訪問的數據庫的位置。

我們可以再配置文件里添加一個連接字符串的配置來定義數據庫的位置

<connectionStrings>
        <add name="OrderSystemContext" connectionString="Data Source=XXX\SQL2008R2;Initial Catalog=OrderSystem;User Id=XXX;Password=XXX" providerName="System.Data.SqlClient"/>
    </connectionStrings>

那么Code First怎么知道使用哪個連接字符串來找到要訪問的數據庫呢?

默認情況下,Code First會在連接字符串的配置節中尋找與你自定的DbContext的子類同名的連接字符串。例如你自定義的DbContext的子類叫OrderSystemContext, 那么name是OrderSystemContext的連接字符串就是你程序中要訪問的數據庫的連接字符串。

如果我們想改變數據庫連接字符串的名字,而不用改變我們自定義的DbContext子類,我們就可以使用DbContext的另一個構造函數

public OrderSystemContext(string databaseName)
            : base(databaseName)
        {

        }

 

我們可以將連接字符串的名字作為參數傳到DbContext子類的構造函數中,然后我們就可以讓我們的DbContext子類和連接字符串的名字脫離關系了.

OrderSystemContext unitOfWork = new OrderSystemContext("OrderSystem");

 

App.Config

<add name="OrderSystem" connectionString="Data Source=CNTSNWV0CN115\SQL2008R2;Initial Catalog=OrderSystem;User Id=ldsng;Password=welcome" providerName="System.Data.SqlClient"/>

還有一個更簡單的方式,如果你想使用固定的連接字符串的名字而不是通過參數把名字傳進來,可以直接在默認構造函數中調用基類的構造函數,傳入固定的連接字符串名稱:

public OrderSystemContext()
            :base("OrderSystem")
        {

        }

 

如果我們程序中同時存在多個DbContext的子類的時候,Entity Framework會為每個DbContext的子類都創建一個數據庫連接,那么我們的程序就保留了很多個數據庫連接的實例。如果我們要優化我們的程序,就可以讓多個DbContext子類使用同一個數據庫連接實例。我們還是要通過重載DbContext的另一個構造函數來實現這個功能。

DbContext的這個構造函數有兩個參數,一個是我們要共用的數據庫連接的實例,另一個是一個開關,用於控制是否由當前的DbContext子類控制數據庫連接實例。如果contextOwnsContext屬性為true,那么當DbContext子類Dispose的時候,就會把共用的DbConnection實例也Dispose掉。如果這個值是false,則數據庫連接實例就需要由程序員自己寫程序釋放。

public OrderSystemContext(DbConnection connection, bool contextOwnsConnection)
            : base(connection, contextOwnsConnection)
        {
        }

 

然后我們可以使用這個構造函數,讓我們的DbContext子類使用共用的數據庫連接實例。

string connectionString = @"Data Source=XXX\SQL2008R2;Initial Catalog=OrderSystem;User Id=XXX;Password=XXX";
           SqlConnection conn = new SqlConnection(connectionString);
           OrderSystemContext unitOfWork = new OrderSystemContext(conn,true);
           ProductRepository repository = new ProductRepository(unitOfWork);
           ProductCatalog catalog = repository.SearchProductCatalog(c => c.CatalogName == "DELL E6400", 1, 10)[0];
           Product product = new Product { Catalog = catalog, CreateDate = DateTime.Parse("2010-2-10"), ExpireDate = DateTime.Parse("2012-2-10") };
           repository.AddNewProduct(product);
           unitOfWork.CommitChanges();

Entity Framework默認會通過一個實現了IDbConnectionFactory接口的類為我們自定義的DbContext類創建數據庫連接。Entity Framework默認提供一個SqlConnectionFactory類用來創建SQL Server的數據庫連接。Entity Framework Code First中Database.DefaultConnectionFactory屬性存儲就是SqlConnectionFactory的對象。

你可以初始化一個新的SqlConnectionFactory的實例,把它賦給Database.DefaultConnectionFactory屬性,你還可以在初始化SqlConnectionFactory的時候,將一些數據庫配置傳進去覆蓋Code First的默認數據庫連接配置

Database.DefaultConnectionFactory = new SqlConnectionFactory(@"Server=XXX\SQL2008R2;Initial Catalog=OrderSystem;User Id=XXX;Password=XXX");

但是有一點比較坑爹,大家一定要牢記,你設置的數據庫連接配置中的數據庫名是無效的。當我使用上面的代碼配置數據庫時,建立的數據庫的名字不是你在SqlConnectionFactory的構造函數中指定的OrderSystem,而是你的DbContext子類的全名(命名空間.類名)

如果你要是想使用自定義的數據庫名稱,你需要重載DbContext子類的構造函數。

public OrderSystemContext(string databaseName)
            : base(databaseName)
        {

        }

在你使用SqlConnectionFactory的情況下,你傳入的databaseName就是你要訪問的數據庫的名字,而不像上面的實例中那樣是連接字符串的名字。

OrderSystemContext unitOfWork = new OrderSystemContext("OrderSystem");

 

通過這篇日記,大家已經清楚怎樣配置數據庫連接。我已經介紹過如何配置數據表中列的屬性,下一次日記中,我將介紹一些高級的列屬性設置。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM