LINQ to SQL活學活用(1):這要打破舊觀念
程序架構
如今比較經典的架構,看看以下圖片。
怎樣實現
在一個N層應用程序中我們怎樣使用LINQ to SQL呢?這給剛剛入門的朋友的確是個難題,使用LINQ to SQL就是ORM技術,能夠非常輕松的實現對數據庫記錄增刪查改操作,可是我們怎樣去“構建它”才更合理,更科學,更好用?這才是我們真正要學習的。使用面向對象的接口、抽象達到這個目的,面向接口編程就是更好的選擇。能夠更好的維護和測試。
以下一步一步完畢這個程序吧,看到標題了嗎?這篇是打破舊觀念。看看接下來有什麽神奇的地方。
首先新建一個project,有兩個類庫分別為:數據訪問層DataAccess和單元測試UnitTest,看看截圖:
數據訪問層
這篇先創建一個數據訪問對象,因為使用LINQ to SQL作為ORM,我們新建一個LINQ to SQL類DataAccessEntities.dbml作為數據訪問對象DataContext。一切可視化的操作,為了展示,在O/R設計器中新建一個Customer類(數據訪問對象)。加入CustomerId、FirstName、LastName三個成員屬性。並在成員屬性的屬性窗體改動對應的屬性。
為了展示,這裏簡單描寫敘述下我的操作,設置成員屬性例如以下:
- CustomerId:成員屬性的類型Int。屬性的名稱CustomerId,數據庫列的名稱CustomerId。數據庫列參與表的主鍵True。插入時在數據庫中自己主動生成值True,指定插入時自己主動同步屬性。
- FirstName:屬性的名稱FirstName,數據庫列的名稱FirstName,其他默認
- LastName:屬性的名稱LastName,數據庫列的名稱LastName,其他默認
好了,簡單的數據訪問對象創建好了,以下測試了~~
單元測試層
單元測試用於測試用例的成功與失敗,在軟件開發中起著尤為重要的地位。當然使用單元測試的要求非常嚴格。這個系列我將嚴格遵守,我整理的要求例如以下
1.盡量在斷言中提供錯誤信息描寫敘述,這能夠非常easy的發現你的錯誤。
2.每一個測試全然獨立。體現面向對象中的單一職責原則。
3.不要假設數據庫中有什麽數據或者哪些數據不在數據庫中,在每一個測試方法前保證數據庫為空的。
4.測試時須要的一些原始數據要作為測試的一部分在測試方法前載入到數據庫中。
遵守上面的要求,就可能面臨以下的麻煩:
- 在測試前刪除每張表的每行數據,PK關聯須要另外寫刪除SQL語句腳本。
- 業務邏輯層創建了你沒有預料到的數據,你不優點理。
- 假設你測試失敗,在數據庫中查看數據不在數據庫中,沒有不論什麽提示信息你不知道系統做了什麽。
- 因為記錄被鎖定,插入數據不寫入數據庫。也不能在不同數據庫連接中讀取。
幸好LINQ to SQL做到了上面的一切,LINQ to SQL的DataContext能夠用來管理數據架構,它提供了DatabaseExists()、DeleteDatabase()、CreateDatabase()方法能夠非常輕松的創建刪除數據庫。
註意。這個系列我使用NUnit.Framework測試,所以要引用nunit.framework.dll程序集。另外因為代碼編寫中涉及了這個類庫引用System.configuration.dll、System.Data.Linq.dll程序集和Business項目。
1.創建一個測試基類
測試一般是非常復雜的,我們創建一個測試基類用於編寫一些通用的方法,然後全部測試類都繼承這個測試基類,這個基類主要完畢以下功能。
第一步:手動配置DataContext連接和日誌
在我們的數據訪問層只創建了一個數據訪問對象,沒有和數據庫打交道,測試時須要對DataContext連接到數據庫。
另外為了測試顯示具體的信息,我們還要使用DataContext的日誌功能。
public string ConnectionString { get { if (ConfigurationManager.ConnectionStrings["conn"] == null || String.IsNullOrEmpty(ConfigurationManager.ConnectionStrings["conn"].ConnectionString) == true) { throw new InvalidOperationException("默認的連接字符串不存在或者為空"); } return ConfigurationManager.ConnectionStrings["conn"].ConnectionString; } } private DataAccessEntitiesDataContext m_dataContext; public DataAccessEntitiesDataContext DataContext { get { if (m_dataContext == null) { m_dataContext = new DataAccessEntitiesDataContext(ConnectionString); m_dataContext.Log = Console.Out; } return m_dataContext; } }
第二步:創建數據庫
在測試之前。打開暫時連接用於創建數據庫。使用DataContext提供了DatabaseExists()、DeleteDatabase()、CreateDatabase()方法,先使用DatabaseExists()驗證數據庫是否存在,假設存在使用DeleteDatabase()方法刪除。使用CreateDatabase()方法創建一個數據庫架構,及時釋放這個連接。
[TestFixtureSetUp] public void Init() { DataAccessEntitiesDataContext context = new DataAccessEntitiesDataContext(ConnectionString); context.Log = Console.Out; if (context.DatabaseExists() == true) { context.DeleteDatabase(); } context.CreateDatabase(); context.Connection.Close(); context.Dispose(); context = null; }
第三步:關閉全部連接
在測試結束關閉全部的連接,這一步非常必要哦。
[TestFixtureTearDown] public void Tear() { DataContext.Connection.Close(); }
第四步:設置連接字符串
新建一App.config文件。設置連接字符串:
<?xml version="1.0" encoding="utf-8" ?> <configuration> <connectionStrings> <add name="conn" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=LINQ;Integrated Security=True"/> </connectionStrings> </configuration>
2.測試類
我們新建一個測試類用於測試數據訪問對象。這裏簡單測試創建一個Customer對象。新建CustomerFixture.cs類繼承UnitTestBase
編寫創建Customer對象方法例如以下,創建一個Customer對象,調用InsertOnSubmit()方法插入,調用DataContext.SubmitChanges()方法提交數據庫。
[Test] public void CreateCustomerTest() { Customer customer = new Customer() { FirstName = "YJing", LastName = "Lee" }; Assert.AreEqual(0, customer.CustomerId, "測試前CustomerId為0"); DataContext.Customer.InsertOnSubmit(customer); DataContext.SubmitChanges(); Assert.AreNotEqual(0, customer.CustomerId, "調用SubmitChanges()方法後CustomerId不為0"); }
測試成功,看看輸出結果:
OH!非常酷!首先創建了數據庫架構,然後插入了一條數據。再次測試一下這種方法將是什麽結果呢?這個問題就留給大家了。
結語
看到了嗎?這就是全新的方式來完畢非常酷的工作!
從面向對象入手。利用LINQ to SQL生成其關系型數據庫。一切就是這麽easy!這篇只在數據訪問層上新建一數據訪問對象,在測試中調用DataContext提供的方法完畢數據操作!
下篇更精彩!
LINQ to SQL活學活用(1):這要打破舊觀念