隨着.NET 4.0時代的到來,開發者愈來愈關注如何能加快開發效率,從而構建健壯的程序。而微軟在.NET 4.0推出的Entity Framework,無疑是值得開發者去學習的,它其實是微軟的ADO.NET的加強版本,是個ORM框架。在本文中,將以例子的形式簡單介紹最新的 Entity Framework 4.1的基本用法。 html
介 紹 web
在舊的Entity 框架中,開發者能夠從已存在的數據庫中產生業務實體的模型,這種開發方法被稱爲數據庫驅動的開發方法。而在4.1的Entity Framework中,支開發者先建立實體業務類,而後再產生相關的數據庫文件,這種開發方法能夠稱爲「代碼先行」的開發方法。這種方法對於開發者來講是 頗有好處的,首先,會讓開發者從面向對象的思惟角度出發,去構建業務邏輯中的實體模型,而後再根據實際的須要去生成數據庫文件,是真正的面向對象的思惟開 發方法。 數據庫
本文中要使用Entity Framework 4.1,這裏提供下載該框架安裝程序:Entity Framework 4.1。 c#
同時,VS.NET 2010也是少不了的,而本文的配套代碼,能夠在這裏下載:VS.NET 2010。 app
本文的例子將會建立兩個類Invoice類和LineItem類。而本文產生的數據庫命名爲Accounting,並會產生兩張表:Invoice和 LineItem。例子中的功能,還包括能夠在gridview中對數據庫中的數據進行增刪改查,最後,還會演示若是類發生了變化了,如何讓相應的數據庫 也發生改變。 框架
步驟1 asp.net
1) 啓動vs.net 2010; ide
2) 新創建一個c#語言的asp.net web工程項目; 函數
3) 將工程命名爲project EF4CodeFirst; 工具
4) 在工程資源管理器中,鼠標右鍵點擊,而後新增一個類,將新增的類命名爲Invoice.cs。
修改這個類的代碼以下:
publicclass Invoice { publicint ID { get; set; } public DateTime InvoiceDate { get; set; } publicdouble Total { get; set; } }
在咱們的類中,有id這個屬性,Entity框架會根據id這個屬性,去生成數據庫表中的對應字段id,若是類中沒定義id這個屬性,則會在數據庫表文件中生成以「類文件名+ID」這樣命名的字段。
在這個Invoice發票類中,存在多個條目LineItem,它們之間明顯構成一對多的關係,因此咱們先創建類LineItem類。
5) 一樣,新增一個LineItem類,代碼以下:
publicclass LineItem { publicint ID { get; set; } publicstring ProductName { get; set; } publicdouble ItemCost { get; set; } publicdouble Units { get; set; } public Invoice Invoice { get; set; } }
在這個類中,維持了對Invoice類的引用,同時也是關聯了Invoice類。
6)而在Invoice類中,也要增長LineItem類的引用,這裏要用到的是集合類,以下代碼:
public ICollection<LineItem> LineItems { get; set; }
同時要在Invovice類的構造函數中,進行初始化LineItem類,以下:
public Invoice() { LineItems =new List<LineItem>(); }
在完成上面的步驟後,則Entity框架已能夠從實體類中建立相關的數據庫和表了,下面繼續進行步驟二。
步驟2
接下來,咱們要引用Entity框架的類庫文件到咱們的工程中。
1) 在工程資源管理器中,鼠標右鍵點擊工程名字,在彈出的菜單中選擇「添加引用」。
2) 在出現的以下圖的界面中,選擇System.Data.Entity ,並點肯定完成:
3) 爲工程繼續增長一個新類,命名爲Accounting.cs ,而且修改其代碼以下:
using System.Data.Entity; publicclass Accounting : DbContext { public Accounting() : base("Accounting") {} public override void OnModelCreating(DbModelBuilder modelBuilder) { base.OnModelCreating(modelBuilder); modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); } public DbSet<Invoice> Invoices { get; set; } public DbSet<LineItem> LineItems { get; set; } }
能夠看到,該類繼承了DbContext類,該類其實是Entity的一個工具類,裏面封裝了不少有用的API,在Accounting類中,分別有兩個DbSet類的實例,它們表明將要在數據庫中生成的兩個表。
構造函數繼承了積累構造函數,並將名爲 「Accounting」 的鏈接字符串做爲參數,以使用該字符串。若是不寫該構造函數,將自動使用與該DbContext同名的鏈接字符串,也就是 name="Accounting" 的連接字符串。
重寫OnModelCreating方法,增長 modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 是爲了在數據庫中生成表時,表名以單數形式出現,不然數據庫中表名爲:Invoices,LineItems。
4)接着須要在web.config中進行添加數據庫鏈接,以下:
<add name="Accounting"
providerName="System.Data.SqlClient"
connectionString="Data Source=(local);Initial Catalog=Accounting;Integrated Security=SSPI;"/>
5) 接着,在default.aspx 中添加gridview控件,而且編寫以下代碼:
using System.Data.Entity; protectedvoid Page_Load(object sender, EventArgs e) { Accounting db =new Accounting(); db.Invoices.Load(); GridView1.DataSource = db.Invoices.Local.ToBindingList(); GridView1.DataBind(); }
記得這裏必須引入System.Data.Entity類庫,而且實例化Accounting對象的實例db,並調用其load方法,加載全部的Invoice數據(這裏咱們通常是加載一對多的一方的數據)。
6)運行工程後,你會發如今SQL SERVER中,會出現了三張表,以下圖:
其中,分別是Invoice表和LineItem表,還有一張表EdmMetadata,是Entity框架爲咱們自動生成的,保存了數據庫中的元數據。另外,能夠看到在表LineItem中,Entity框架已經爲咱們自動生成了外鍵Invoice_ID,以下圖:
步驟三
如今,既然數據庫已經建立了,則能夠爲其增長一些數據了,在page_load中增長以下代碼:
protectedvoid Page_Load(object sender, EventArgs e) { Accounting db =new Accounting(); Invoice invoice =new Invoice { InvoiceDate = DateTime.Now, Total =1000 }; db.Invoices.Add(invoice); db.SaveChanges(); db.Invoices.Load(); GridView1.DataSource = db.Invoices.Local.ToBindingList(); GridView1.DataBind(); }
在這裏咱們實例化了Invoice類的一個實例,添加了相關的數據內容,而後使用db.Invoices.Add增長到Account類的DBSet屬性中,最後調用savechanges方法保存到數據庫中,運行後,能夠看到以下效果:
如今咱們試下更新數據,代碼以下:
protectedvoid Page_Load(object sender, EventArgs e) { Accounting db =new Accounting(); Invoice invoice =new Invoice { ID =1, InvoiceDate = DateTime.Now, Total =900 }; db.Entry(invoice).State = EntityState.Modified; db.SaveChanges(); db.Invoices.Load(); GridView1.DataSource = db.Invoices.Local.ToBindingList(); GridView1.DataBind(); }
這裏把invoice實例的成員變量的ID改成1,注意在更新時,設置其狀態(state)爲EntityState.Modified,表示是修改記錄,最後再保存,運行後,能夠看到數據庫中的數據的確更新了,全部這些都是Entity 框架在起做用。
最後學習刪除記錄,代碼以下:
protectedvoid Page_Load(object sender, EventArgs e) { Accounting db =new Accounting(); Invoice invoice =new Invoice { ID =1, InvoiceDate = DateTime.Now, Total =900 }; db.Invoices.Remove(invoice); db.SaveChanges(); db.Invoices.Load(); GridView1.DataSource = db.Invoices.Local.ToBindingList(); GridView1.DataBind(); }
這裏只須要調用Remove方法,便可在數據庫中刪除該記錄。
步驟4
在這個步驟中,咱們學習如何改變數據模型。假設咱們要在Invoice類中增長一個Tax的屬性,也須要Entity框架同步在數據庫中增長這個字段,下面演示其步驟:
1)咱們在Invoice類中增長Tax這個屬性。
2)若是這時運行工程,則會看到以下的錯誤提示:
The model backing the 'Accounting' context has changed since the database was
created. Either manually delete/update the database, or call
Database.SetInitializer with an IDatabaseInitializer instance. For example, the
DropCreateDatabaseIfModelChanges strategy will automatically delete and recreate
the database, and optionally seed it with new data.
提示告訴咱們,或者這個時候從新手工刪除數據庫或者使用代碼的方法去完成,咱們使用代碼的方法去完成,只須要在Application_Start事件中編碼以下,便可讓Entity框架,自動把新增長的屬性反映到數據庫中:
void Application_Start(object sender, EventArgs e) { // Code that runs on application startup System.Data.Entity.Database.SetInitializer<Accounting> (new System.Data.Entity.DropCreateDatabaseIfModelChanges<Accounting>()); }
3) 再次運行工程,會看到數據表中的確增長了Tax這個字段了,以下圖:
步驟5
注意,在上面的步驟4中,若是類的屬性發生變化,則實際上是經過代碼的方法,從新將舊的數據庫DROP掉,而後再新建,這樣的話費時費力,而能夠經過另外的一個方法實現,即還好咱們能夠在初始化的過程當中添加測試數據,這樣每次從新建立數據庫的時候,測試數據就會自動加進去了,算是解決了一些問題,方法以下:
1)在工程項目中,新增長一個類,命名爲AccountingInitializer.cs
2)修改其代碼以下:
publicclass AccountingInitializer : System.Data.Entity.DropCreateDatabaseIfModelChanges<Accounting> { protectedoverridevoid Seed(Accounting context) { Invoice invoice =new Invoice { Total =20, InvoiceDate = new DateTime(2011, 4, 14), Tax =1.50 }; invoice.LineItems.Add(new LineItem { ItemCost =2, ProductName ="Test", Units =4 }); invoice.LineItems.Add(new LineItem { ItemCost =4, ProductName ="Test 2", Units =3 }); context.Invoices.Add(invoice); context.SaveChanges(); base.Seed(context); } }
其中,在這個類中繼承了DropCreateDatabaseIfModelChanges這個類,而且重寫了seed這個方法,在這個方法中能夠編寫新增測試數據。要記得還須要在Application_OnStart事件中編寫以下代碼:
void Application_Start(object sender, EventArgs e)
{
//在啓動過程當中執行該段代碼
System.Data.Entity.Database.SetInitializer<Accounting>
(new AccountingInitializer());
}
小 結
能夠看到,Entity Framework 4.1的確方便了用戶的開發操做,能讓用戶更專一於業務邏輯實體的開發,更符合OOP的思惟方式,更多關於Entity Framework的操做,請參考微軟的MSDN