code first基础
隨著.NET 4.0時(shí)代的到來(lái),開(kāi)發(fā)者越來(lái)越關(guān)注如何能加快開(kāi)發(fā)效率,從而構(gòu)建健壯的程序。而微軟在.NET 4.0推出的Entity Framework,無(wú)疑是值得開(kāi)發(fā)者去學(xué)習(xí)的,它實(shí)際上是微軟的ADO.NET的增強(qiáng)版本,是個(gè)ORM框架。在本文中,將以例子的形式簡(jiǎn)單介紹最新的 Entity Framework 4.1的基本用法。
介 紹
在舊的Entity 框架中,開(kāi)發(fā)者可以從已存在的數(shù)據(jù)庫(kù)中產(chǎn)生業(yè)務(wù)實(shí)體的模型,這種開(kāi)發(fā)方法被稱為數(shù)據(jù)庫(kù)驅(qū)動(dòng)的開(kāi)發(fā)方法。而在4.1的Entity Framework中,支開(kāi)發(fā)者先創(chuàng)建實(shí)體業(yè)務(wù)類,然后再產(chǎn)生相關(guān)的數(shù)據(jù)庫(kù)文件,這種開(kāi)發(fā)方法可以稱為“代碼先行”的開(kāi)發(fā)方法。這種方法對(duì)于開(kāi)發(fā)者來(lái)說(shuō)是 很有好處的,首先,會(huì)讓開(kāi)發(fā)者從面向?qū)ο蟮乃季S角度出發(fā),去構(gòu)建業(yè)務(wù)邏輯中的實(shí)體模型,然后再根據(jù)實(shí)際的需要去生成數(shù)據(jù)庫(kù)文件,是真正的面向?qū)ο蟮乃季S開(kāi) 發(fā)方法。
本文中要使用Entity Framework 4.1,這里提供下載該框架安裝程序:Entity Framework 4.1。
同時(shí),VS.NET 2010也是少不了的,而本文的配套代碼,可以在這里下載:VS.NET 2010。
本文的例子將會(huì)創(chuàng)建兩個(gè)類Invoice類和LineItem類。而本文產(chǎn)生的數(shù)據(jù)庫(kù)命名為Accounting,并會(huì)產(chǎn)生兩張表:Invoice和 LineItem。例子中的功能,還包括可以在gridview中對(duì)數(shù)據(jù)庫(kù)中的數(shù)據(jù)進(jìn)行增刪改查,最后,還會(huì)演示如果類發(fā)生了變化了,如何讓相應(yīng)的數(shù)據(jù)庫(kù) 也發(fā)生改變。
步驟1
1) 啟動(dòng)vs.net 2010;
2) 新建立一個(gè)c#語(yǔ)言的asp.net web工程項(xiàng)目;
3) 將工程命名為project EF4CodeFirst;
4) 在工程資源管理器中,鼠標(biāo)右鍵點(diǎn)擊,然后新增一個(gè)類,將新增的類命名為Invoice.cs。
修改這個(gè)類的代碼如下:
publicclass Invoice { publicint ID { get; set; } public DateTime InvoiceDate { get; set; } publicdouble Total { get; set; } }在我們的類中,有id這個(gè)屬性,Entity框架會(huì)根據(jù)id這個(gè)屬性,去生成數(shù)據(jù)庫(kù)表中的對(duì)應(yīng)字段id,如果類中沒(méi)定義id這個(gè)屬性,則會(huì)在數(shù)據(jù)庫(kù)表文件中生成以“類文件名+ID”這樣命名的字段。
在這個(gè)Invoice發(fā)票類中,存在多個(gè)條目LineItem,它們之間明顯構(gòu)成一對(duì)多的關(guān)系,所以我們先建立類LineItem類。
5) 同樣,新增一個(gè)LineItem類,代碼如下:
publicclass LineItem { publicint ID { get; set; } publicstring ProductName { get; set; } publicdouble ItemCost { get; set; } publicdouble Units { get; set; } public Invoice Invoice { get; set; } }在這個(gè)類中,維持了對(duì)Invoice類的引用,同時(shí)也是關(guān)聯(lián)了Invoice類。
6)而在Invoice類中,也要增加LineItem類的引用,這里要用到的是集合類,如下代碼:
public ICollection<LineItem> LineItems { get; set; }
同時(shí)要在Invovice類的構(gòu)造函數(shù)中,進(jìn)行初始化LineItem類,如下:
public Invoice() {LineItems =new List<LineItem>(); }在完成上面的步驟后,則Entity框架已可以從實(shí)體類中創(chuàng)建相關(guān)的數(shù)據(jù)庫(kù)和表了,下面繼續(xù)進(jìn)行步驟二。
步驟2
接下來(lái),我們要引用Entity框架的類庫(kù)文件到我們的工程中。
1) 在工程資源管理器中,鼠標(biāo)右鍵點(diǎn)擊工程名字,在彈出的菜單中選擇“添加引用”。
2) 在出現(xiàn)的如下圖的界面中,選擇System.Data.Entity ,并點(diǎn)確定完成:
3) 為工程繼續(xù)增加一個(gè)新類,命名為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類,該類實(shí)際上是Entity的一個(gè)工具類,里面封裝了很多有用的API,在Accounting類中,分別有兩個(gè)DbSet類的實(shí)例,它們代表將要在數(shù)據(jù)庫(kù)中生成的兩個(gè)表。
構(gòu)造函數(shù)繼承了積累構(gòu)造函數(shù),并將名為 “Accounting” 的連接字符串作為參數(shù),以使用該字符串。如果不寫(xiě)該構(gòu)造函數(shù),將自動(dòng)使用與該DbContext同名的連接字符串,也就是 name="Accounting" 的鏈接字符串。
重寫(xiě)OnModelCreating方法,增加 modelBuilder.Conventions.Remove<PluralizingTableNameConvention>(); 是為了在數(shù)據(jù)庫(kù)中生成表時(shí),表名以單數(shù)形式出現(xiàn),否則數(shù)據(jù)庫(kù)中表名為:Invoices,LineItems。
4)接著需要在web.config中進(jìn)行添加數(shù)據(jù)庫(kù)連接,如下:
<add name="Accounting"
providerName="System.Data.SqlClient"
connectionString="Data Source=(local);Initial Catalog=Accounting;Integrated Security=SSPI;"/>
5) 接著,在default.aspx 中添加gridview控件,并且編寫(xiě)如下代碼:
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類庫(kù),并且實(shí)例化Accounting對(duì)象的實(shí)例db,并調(diào)用其load方法,加載所有的Invoice數(shù)據(jù)(這里我們一般是加載一對(duì)多的一方的數(shù)據(jù))。
6)運(yùn)行工程后,你會(huì)發(fā)現(xiàn)在SQL SERVER中,會(huì)出現(xiàn)了三張表,如下圖:
其中,分別是Invoice表和LineItem表,還有一張表EdmMetadata,是Entity框架為我們自動(dòng)生成的,保存了數(shù)據(jù)庫(kù)中的元數(shù)據(jù)。另外,可以看到在表LineItem中,Entity框架已經(jīng)為我們自動(dòng)生成了外鍵Invoice_ID,如下圖:
步驟三
現(xiàn)在,既然數(shù)據(jù)庫(kù)已經(jīng)創(chuàng)建了,則可以為其增加一些數(shù)據(jù)了,在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(); }在這里我們實(shí)例化了Invoice類的一個(gè)實(shí)例,添加了相關(guān)的數(shù)據(jù)內(nèi)容,然后使用db.Invoices.Add增加到Account類的DBSet屬性中,最后調(diào)用savechanges方法保存到數(shù)據(jù)庫(kù)中,運(yùn)行后,可以看到如下效果:
現(xiàn)在我們?cè)囅赂聰?shù)據(jù),代碼如下:
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實(shí)例的成員變量的ID改為1,注意在更新時(shí),設(shè)置其狀態(tài)(state)為EntityState.Modified,表示是修改記錄,最后再保存,運(yùn)行后,可以看到數(shù)據(jù)庫(kù)中的數(shù)據(jù)的確更新了,所有這些都是Entity 框架在起作用。
最后學(xué)習(xí)刪除記錄,代碼如下:
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(); }這里只需要調(diào)用Remove方法,即可在數(shù)據(jù)庫(kù)中刪除該記錄。
步驟4
在這個(gè)步驟中,我們學(xué)習(xí)如何改變數(shù)據(jù)模型。假設(shè)我們要在Invoice類中增加一個(gè)Tax的屬性,也需要Entity框架同步在數(shù)據(jù)庫(kù)中增加這個(gè)字段,下面演示其步驟:
1)我們?cè)贗nvoice類中增加Tax這個(gè)屬性。
2)如果這時(shí)運(yùn)行工程,則會(huì)看到如下的錯(cuò)誤提示:
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.
提示告訴我們,或者這個(gè)時(shí)候重新手工刪除數(shù)據(jù)庫(kù)或者使用代碼的方法去完成,我們使用代碼的方法去完成,只需要在Application_Start事件中編碼如下,即可讓Entity框架,自動(dòng)把新增加的屬性反映到數(shù)據(jù)庫(kù)中:
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) 再次運(yùn)行工程,會(huì)看到數(shù)據(jù)表中的確增加了Tax這個(gè)字段了,如下圖:
步驟5
注意,在上面的步驟4中,如果類的屬性發(fā)生變化,則其實(shí)是通過(guò)代碼的方法,重新將舊的數(shù)據(jù)庫(kù)DROP掉,然后再新建,這樣的話費(fèi)時(shí)費(fèi)力,而可以通過(guò)另外的一個(gè)方法實(shí)現(xiàn),即還好我們可以在初始化的過(guò)程中添加測(cè)試數(shù)據(jù),這樣每次重新創(chuàng)建數(shù)據(jù)庫(kù)的時(shí)候,測(cè)試數(shù)據(jù)就會(huì)自動(dòng)加進(jìn)去了,算是解決了一些問(wèn)題,方法如下:
1)在工程項(xiàng)目中,新增加一個(gè)類,命名為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); } }其中,在這個(gè)類中繼承了DropCreateDatabaseIfModelChanges這個(gè)類,并且重寫(xiě)了seed這個(gè)方法,在這個(gè)方法中可以編寫(xiě)新增測(cè)試數(shù)據(jù)。要記得還需要在Application_OnStart事件中編寫(xiě)如下代碼:
void Application_Start(object sender, EventArgs e)
{
//在啟動(dòng)過(guò)程中執(zhí)行該段代碼
System.Data.Entity.Database.SetInitializer<Accounting>
(new AccountingInitializer());
}
小 結(jié)
可以看到,Entity Framework 4.1的確方便了用戶的開(kāi)發(fā)操作,能讓用戶更專注于業(yè)務(wù)邏輯實(shí)體的開(kāi)發(fā),更符合OOP的思維方式,更多關(guān)于Entity Framework的操作,請(qǐng)參考微軟的MSDN
轉(zhuǎn)載于:https://www.cnblogs.com/asks/p/4372790.html
總結(jié)
以上是生活随笔為你收集整理的code first基础的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: (Lesson2)根据类名称和属性获得元
- 下一篇: android studio 模拟器中文