本人在學習EF4時,讀了很多書,走了很多彎路,最后發現其實EF4很簡單,結合Linq,可以實現非常簡單的添查刪改操作。下面以一個實例為例對EF4的使用作一解析,希望大家在此少走彎路。本文采用較為成熟的Database First模式,從數據庫生成模型,然后使用T4模板生成POCO類代碼,最后使用控制台程序進行調用。
1、數據庫准備
本文選擇的數據庫是一個在實際工作中非常常用的數據庫, 構造如下:
各個表的結構和數據類型如下:
- ProductUnit表:產品單位
- Products表:產品信息表
- ProductBigType:產品大類
- ProductSmallType:產品小類
依照上述步驟在Sql Server Management Studio編寫完成后,就可以准備進行調用了。
2.准備相關工具
相信手邊VS已經安裝完畢,還要下載Entity Framework 4.x來進行安裝,除此以外還需要一個重要的工具:
EF4.x POCO Entity Generator for C#,想要安裝這一工具,點擊VS的工具菜單下的擴展管理器,,,,在搜索框中搜索POCO字樣就可以找到。這個工具實際上是一個T4模板,通過它可以為我們自動生成POCO式的實體類以及對ObjectContext的引用。
3、生成實體的POCO類
1)首先新建一個控制台項目,命名為ProdouctEFDemo;
2) 在該項目的根結點上右鍵單擊,在彈出的菜單里選擇添加→新建文件夾,新建一個命名為Models的文件夾,數據模型將放在這里。
3)在Models文件夾上右鍵單擊,在彈出的菜單里選擇添加→新建項,在彈出的對話框中選擇ADO.Net實體數據模型,並將其命名為ProductEFDemo.edmx;單擊添加按鈕繼續;
4)選擇“從數據庫生成”,單擊下一步繼續;
5)點擊新建連接,找到需要生成實體的數據庫(這一步就不用演示了吧!)
注意勾選“將App.Config中的實體連接設置另存為”選項,本對話框中的ProductsEntities就是未來實體對象的類名,建議不要更改。觀察一下實體連接字符串,哇好復雜,不用管他。操作完成后單擊下一步繼續:
6)選擇全部的表,並注意勾選“在模型中加入外鍵列”,這一選項是EF4新增的,在實際應用中有很多好處,特別是在構建模型時,單擊完成按鈕就會在Models文件夾下生成實體數據模型:
注意檢查VS的“輸出”窗口,是否提示有生成錯誤等信息,如果有錯誤,就需要從“錯誤列表”窗口查看是什么出了錯,一一解決。最常見的錯誤是表沒有設置主鍵列,這會導致在進行數據插入時出現一些莫名其妙的錯誤,所以有關的檢查在這一步都要完成,否則后面出了錯很難調試。當然高手也可以通過手工悠edmx文件來解決(這個文件實際上就是一個XML文件),但是既然有可視化編輯器,為什么不讓問題消失在萌芽中呢?
7)現在進入最高級的一步:生成實體類。VS默認已經有兩個可供使用的實體類生成器,但個人覺得都不是很好用,沒有生成POCO類,理解起來也困難。有了前面介紹的EF4.x POCO Entity Generator,問題迎刃而解。在VS中的ProductEFDemo.edmx的設計器界面任意的空白處點擊右鍵,在彈出的菜單中選擇“添加代碼生成項”,在彈出的對話框選擇EF4.x POCO Entity Generator,為其隨便起一個名字:
點擊添加后,Models文件夾下就出現了兩個T4模板,並且同時自動運行T4生成器,為我們生成了所需要的實體POCO代碼。你可以花一點時間研究一下這些代碼,在這里因為篇幅原因,就不再拷貝代碼了:
如果代碼沒有自動生成,可以在兩個T4模板上分別點擊左鍵,在彈出的菜單里選擇“運行自定義工具”命令,可以得到同樣的效果。
現在大功告成,可以動手進行我們的添查刪改操作了。
4、向數據庫添加測試數據:
為了簡單起見,我們向數據庫添加的數據符合這樣的規則:如果字符串類型,內容為XX測試數據+序號,如果為decimal類型,內容為隨機的double類型數據,如果是時間類型,內容為DateTime.Today;為此我們逐個向數據庫添加數據,向數據庫里添加數據的原則是:如果是一對多關系,先添加一的部分,再添加多的部分,否則多的部分會因為沒有數據可用而引發異常,在本示例里,Product表是多的部分,而ProductUnit是一的部分,所以添加數據的順序應為ProductUnit→ProductBigType→ProductSmallType→Product:
在項目中再添加一個文件夾,命名為Business,將我們進行添查刪改的代碼都放在里面,新建一個靜態類InsertData,cs:
using System; using System.Collections.Generic; using System.Linq; using System.Text; using ProductEFDemo.Models; namespace ProductEFDemo.Business { public static class InsertData { public static void AddProudctUnit() { for (int i = 0; i < 10; i++) { var productUnit = new ProductUnit { ProductUnitId=Guid.NewGuid(), ProductUnitName = String.Format("產品單位測試數據{0}",i.ToString()) }; using (var ctx = new ProductsEntities()) { ctx.ProductUnit.AddObject(productUnit); ctx.SaveChanges(); } } } } }
好了,基本的ProductUnit的數據錄入問題得到圓滿解決。這里對代碼作一個解釋:
在命名空間務必要添加對ProductEFDemo.Models的引用,因為實體的POCO類,ObjectContext類都在這呢!
然后就可以自由地調用相關的類了,注意這句:
using (var ctx = new ProductsEntities()) { ctx.ProductUnit.AddObject(productUnit); ctx.SaveChanges(); }
適用於所有情況,其中ctx是ObjectContext類的實例,調用AddObject方法就可以將對象加入ObjectContext,然后再調用SaveChanges方法就可以將數據更新到數據庫。是不是很簡單?
如法泡制:
public static void AddProductBigType() { for (int i = 0; i < 10; i++) { var productBigType = new ProductBigType { ProductBigTypeId = Guid.NewGuid(), ProductBigTypeName = String.Format("產品大類測試數據{0}", i.ToString()) }; using (var ctx = new ProductsEntities()) { ctx.ProductBigType.AddObject(productBigType); ctx.SaveChanges(); } } }public static void AddProductSmallType(Guid productBigTypeId) { for (int i = 0; i < 10; i++) { var productSmallType = new ProductSmallType { ProductBigTypeId=productBigTypeId, ProductSmallTypeId=Guid.NewGuid(), ProductSmallTypeName = String.Format("產品小類測試數據{0}", i.ToString()) }; using (var ctx = new ProductsEntities()) { ctx.ProductSmallType.AddObject(productSmallType); ctx.SaveChanges(); } } } public static void AddProduct(Guid productUnitId,Guid productSmallTypeId) { for (int i = 0; i < 10; i++) { var rand = new Random(); var product = new Product() { ProductId=Guid.NewGuid(), ProductName=string.Format ("產品名稱測試數據{0}",i.ToString()), ProductSmallTypeId=productSmallTypeId, ProductUnitId=productUnitId, ProductBasePrice=(decimal)(rand.NextDouble()*100), ProductLosePrice=(decimal)(rand.NextDouble()*50) }; using (var ctx = new ProductsEntities()) { ctx.Product.AddObject(product); ctx.SaveChanges(); } } }SQL表生成代碼下載:/Files/qouoww/sql.zip
聲明:本文系本人原創,版權歸屬作者和博客園共同所有,任何組織或個人不得隨意轉載,修改。需要轉載請與本人聯系:qouoww@163.com。