【转】学习Entity Framework 中的Code First
這是上周就寫(xiě)好的文章,是在公司浩哥的建議下寫(xiě)的,本來(lái)是部門(mén)里面分享求創(chuàng)新用的,這里貼出來(lái)分享給大家。
?
最近在對(duì)MVC的學(xué)習(xí)過(guò)程中,接觸到了Code First這種新的設(shè)計(jì)模式,感覺(jué)很新穎,并且也體驗(yàn)到了這種方式所帶來(lái)的便利。這里將我的一些理解分享出來(lái)。
需要了解的概念
POCO
POCO(Plain Old CLR Object)的概念是從java的POJO借用而來(lái),而兩者的含義是一致的,不同的僅僅是使用的語(yǔ)言不一樣。所以POCO的解釋就是“Plain Old C# Object”。POJO的內(nèi)在含義是指那些沒(méi)有從任何類繼承、也沒(méi)有實(shí)現(xiàn)任何接口,更沒(méi)有被其它框架侵入的對(duì)象。
?PO
PO是指持久對(duì)象(persistant object持久對(duì)象)。持久對(duì)象實(shí)際上必須對(duì)應(yīng)數(shù)據(jù)庫(kù)中的entity,所以和POJO有所區(qū)別。比如說(shuō)POJO是由new創(chuàng)建,由GC回收。但是持久對(duì)象是 insert數(shù)據(jù)庫(kù)創(chuàng)建,由數(shù)據(jù)庫(kù)delete刪除的?;旧铣志脤?duì)象?? 生命周期和數(shù)據(jù)庫(kù)密切相關(guān)。另外持久對(duì)象往往只能存在一個(gè)數(shù)據(jù)庫(kù) Connection之中,Connnection關(guān)閉以后,持久對(duì)象就不存在了,而POJO只要不被GC回收,總是存在的。
?ORM
ORM(Object/Relational Mapping) 對(duì)象關(guān)系映射,主要是把數(shù)據(jù)庫(kù)中的關(guān)系數(shù)據(jù)映射稱為程序中的對(duì)象
?NHibernate?
NHibernate是一個(gè)面向.NET環(huán)境的對(duì)象/關(guān)系數(shù)據(jù)庫(kù)映射工具。對(duì)象/關(guān)系數(shù)據(jù)庫(kù)映射(object/relational mapping,ORM)這個(gè)術(shù)語(yǔ)表示一種技術(shù),用來(lái)把對(duì)象模型表示的對(duì)象映射到基于SQL的關(guān)系模型數(shù)據(jù)結(jié)構(gòu)中去。所以NHibernate與Entity Framework是很相近的。
?Entity Framework
Entity Framework的全稱是ADO.NET Entity Framework,是微軟開(kāi)發(fā)的基于ADO.NET的ORM(Object/Relational Mapping)框架。
其架構(gòu)圖如下:
?
?
?
?
在接手一個(gè)新項(xiàng)目時(shí)我們所熟知及習(xí)慣使用的設(shè)計(jì)方式,是在分析需求后開(kāi)始創(chuàng)建數(shù)據(jù)庫(kù)中的表,一旦表確定后變動(dòng)不會(huì)太大或者幾乎不再去更改表的結(jié)構(gòu),后面的模型編寫(xiě)及業(yè)務(wù)邏輯的編寫(xiě)都在這個(gè)基礎(chǔ)上進(jìn)行。這種方式稱為Database First。
而在2011四月發(fā)布的Entity Framework 4中存在三種工作方式,他們分別為:Code First, Model First和Database First。其中本文要討論的Code First就是新增的一種方式。
Code First
為了支持以設(shè)計(jì)為中心的開(kāi)發(fā)流程,EF4 還更多地支持以代碼為中心 (code-centric) ,我們稱為代碼優(yōu)先的開(kāi)發(fā),代碼優(yōu)先的開(kāi)發(fā)支持更加優(yōu)美的開(kāi)發(fā)流程,它允許你:
在不使用設(shè)計(jì)器或者定義一個(gè) XML 映射文件的情況下進(jìn)行開(kāi)發(fā)。
·允許編寫(xiě)簡(jiǎn)單的模型對(duì)象POCO (plain old classes),而不需要基類。
·通過(guò)"約定優(yōu)于配置",使得數(shù)據(jù)庫(kù)持久層不需要任何的配置
·也可以覆蓋"約定優(yōu)于配置",通過(guò)流暢的 API 來(lái)完全定制持層的映射。
Code First是基于Entity Framework的新的開(kāi)發(fā)模式,原先只有Database First和Model First兩種。Code First顧名思義,就是先用C#/VB.NET的類定義好你的領(lǐng)域模型,然后用這些類映射到現(xiàn)有的數(shù)據(jù)庫(kù)或者產(chǎn)生新的數(shù)據(jù)庫(kù)結(jié)構(gòu)。Code First同樣支持通過(guò)Data Annotations或fluent API進(jìn)行定制化配置。
其他兩種設(shè)計(jì)方式
?? Database First是最老也是應(yīng)用得最廣泛的一種設(shè)計(jì)方式。如上文提到過(guò)的那樣,Database First這種方式的設(shè)計(jì)高度依賴于數(shù)據(jù)庫(kù)中表的結(jié)構(gòu),根據(jù)表及表間的關(guān)系來(lái)創(chuàng)建模型。如果后期需求有所變更或者功能有很大變化的話,需要涉及到更改數(shù)據(jù)庫(kù)所付出的代價(jià)將會(huì)很大,因?yàn)橹熬帉?xiě)好的代碼將不再適用于新的表,我們必需重構(gòu)以更改代碼中的邏輯以適應(yīng)更改之后的表。
?? Model Firstj是創(chuàng)建ADO.NET實(shí)體對(duì)象以及它們之間的關(guān)系,然后再指定到數(shù)據(jù)庫(kù)的映射。這個(gè)實(shí)體對(duì)象即為Model。
在MVC中使用CodeFirst
這里我將用一個(gè)非常簡(jiǎn)單的例子來(lái)演示一下Code First在MVC中的使用,主要還是展示Code First 具體是怎么工作的。
Note:你可能需要單獨(dú)安裝Entity Framework 4.1
ADO.NET Entity Framework 4.1 安裝文件下載地址:http://www.microsoft.com/download/en/details.aspx?displaylang=en&id=8363
?
下面我們開(kāi)始這個(gè)例子。既然是Code First,就是以代碼為中心進(jìn)行設(shè)計(jì),所以我們并不關(guān)心具體的數(shù)據(jù)庫(kù)構(gòu)造到底是怎么樣的。我們從分析需求開(kāi)始,即我們要實(shí)現(xiàn)的功能。這里我僅僅是要實(shí)現(xiàn)一個(gè)展示博客列表的頁(yè)面,這里我們不關(guān)注CRUD的實(shí)現(xiàn),因?yàn)檫@些都可以在MVC里自動(dòng)生成。這里我們將看到,整個(gè)過(guò)程我們沒(méi)有寫(xiě)sql語(yǔ)句,也沒(méi)有用sql server management studio 在數(shù)據(jù)庫(kù)里進(jìn)行表的設(shè)計(jì),但我們運(yùn)行程序時(shí),這些需要的表就已經(jīng)自動(dòng)創(chuàng)建好了,并且我們?cè)陧?yè)面進(jìn)行CRUD操作時(shí),也是與數(shù)據(jù)庫(kù)里面的數(shù)據(jù)是完全同步的。
打開(kāi)VS2010新建一個(gè)MVC3項(xiàng)目,注意環(huán)境要設(shè)為.Net Framework 4。這里我將項(xiàng)目命名為MvcBlog。
?
?
選擇空的模板,View engine我們用ASPX。
?
?
因?yàn)镃ode First需要EntityFramework支持,項(xiàng)目創(chuàng)建好后在引用里面系統(tǒng)已經(jīng)自動(dòng)為我們引用了EntityFramework程序集,如果沒(méi)有需要手動(dòng)引用進(jìn)來(lái)。
?
?
(為了展示完整的目錄層結(jié)構(gòu),在圖片上我把中間很多引用去掉換以省略號(hào)代替,所以你看到這張圖片時(shí)不要感到奇怪,我的VS不是特別定制版的)?
我們首先在Model中創(chuàng)建一個(gè)博客類來(lái)保存一篇博客的基本信息,它包含一個(gè)博客標(biāo)識(shí)BlogId, 標(biāo)題Title還有創(chuàng)建日期CreateDate。
在Model文件夾上右擊選擇Add->Class。
?
?
在Name中輸入Blog再點(diǎn)擊Add。
?
其中的代碼如下:
1 namespace MvcBlog.Models2 3 {4 5 public class Blog6 7 {8 9 public int BlogId { get; set; } 10 11 public string Title { get; set; } 12 13 14 15 public DateTime CreateDate { get; set; } 16 17 } 18 19 }?
同樣的方法我們?cè)傩陆ㄒ粋€(gè)類,命名為BlogEntities.cs,這個(gè)類跟Blog類的功能是不同的,我們將在代碼里將它定義為從DBContex繼承,這樣這個(gè)BlogEntities上下文類將扮演著與數(shù)據(jù)庫(kù)溝通的重要角色,在這里面可以定義需要的表,項(xiàng)目運(yùn)行后這些表將自動(dòng)在數(shù)據(jù)庫(kù)創(chuàng)建。這里,我們用剛才定義好的Blog來(lái)定義一個(gè)Dbset,代碼如下:
?
1 public class BlogEntities:DbContext 2 3 { 4 5 public DbSet<Blog> Blogs { get; set; } 6 7 }?
(注意:這里需要在文件頂部添加using System.Data.Entity引用語(yǔ)句才能使用DbContext及DbSet)
?
上面我們把模型準(zhǔn)備好了,現(xiàn)在定義Controller。但在進(jìn)行這一步前,我們需要Ctrl+Shift+B編譯一下程序,以便系統(tǒng)知道我們之前定義好的Blog類和BlogEntities類。右擊Controllers文件夾選擇Add->Controller打開(kāi)添加Controller對(duì)話框,將其命名為HomeController(MVC的Controller,當(dāng)然你也可以隨便命名,只不過(guò)在打開(kāi)網(wǎng)頁(yè)時(shí)需要手動(dòng)輸入路徑),此刻數(shù)據(jù)庫(kù)還沒(méi)有被創(chuàng)建,并且呆會(huì)自動(dòng)創(chuàng)建后里面也是空的沒(méi)有數(shù)據(jù),我們需要向里面添加一些數(shù)據(jù),所以這里模板我們選擇帶有CRUD(增刪除改查)功能的,再將下面的模型類選為Blog,上下文類選為BlogEntities,系統(tǒng)會(huì)自動(dòng)實(shí)現(xiàn)CRUD操作,不用我們手動(dòng)編寫(xiě)。
(注意:之前必需編譯一下,才能在這一步的下拉菜單里找到我們已經(jīng)定義好的類)
?
?
單擊Add之后,生成的代碼大概是這樣:
+ View Code
?
視圖已經(jīng)自動(dòng)添加在了Views文件夾下,到此我們的程序已經(jīng)能夠工作了,雖然我們似乎什么都沒(méi)做。在運(yùn)行前我們可以打開(kāi)Sql server management studio (或者在VS里用服務(wù)器管理器連接到你本地的數(shù)據(jù)庫(kù))查看一下以確定數(shù)據(jù)庫(kù)里還沒(méi)有我們程序里需要的Blog表。然后我們Ctrl+F5運(yùn)行網(wǎng)站。
?
?
頁(yè)面顯示出了我們?cè)贐log中定義的Title字段和CreateDate字段,但由于還沒(méi)有數(shù)據(jù)來(lái)進(jìn)行顯示,所以只有標(biāo)題。
這個(gè)時(shí)候,我們斷開(kāi)數(shù)據(jù)庫(kù)再重新連接,就會(huì)發(fā)現(xiàn)EF創(chuàng)建了一個(gè)程序命名空間為名稱的數(shù)據(jù)庫(kù)MvcBlog.Models.BlogEntities,里面包含我們用Dbset定義的Blogs表。表中的列也正好與我們?cè)贐log類中定義的字段相對(duì)應(yīng)。
?
?
?
仔細(xì)觀察你會(huì)發(fā)現(xiàn),它自動(dòng)將BlogId定義為了主鍵,這是EF的convention在起作用,如果我們沒(méi)有顯示地指定數(shù)據(jù)庫(kù)的連接字符串等配置信息,這些值將會(huì)遵從EF里的約定進(jìn)行取值,比如這里的數(shù)據(jù)庫(kù)名 MvcBlog.Models.BlogEntities。
這樣的名稱當(dāng)然不是我們想要的,而且,如果我們本地安裝了多個(gè)數(shù)據(jù)庫(kù)實(shí)例的話,我們也希望指定項(xiàng)目將數(shù)據(jù)創(chuàng)建在我們想要的實(shí)例當(dāng)中。要覆蓋默認(rèn)的約定,我們只需在Web.config(注意:不是Views文件夾下的Web.config)里添加一下對(duì)數(shù)據(jù)庫(kù)的配置信息,代碼如下:
<connectionStrings><add name="BlogEntities"connectionString="server=(local)\sqlexpress;database=MvcBlog;integrated security=true;"providerName="System.Data.SqlClient"/></connectionStrings>?
注意上面的name應(yīng)和Models中的定義的上下文類名稱相同,這樣才能使EF正常工作。server換成你本機(jī)數(shù)據(jù)庫(kù)實(shí)例的名字。現(xiàn)在我們可以看到在先前那個(gè)數(shù)據(jù)庫(kù)上方它生成了我們重新命名的數(shù)據(jù)庫(kù)。
?
?
?
重新運(yùn)行程序,我們?cè)陧?yè)面中點(diǎn)擊Create New來(lái)添加幾條數(shù)據(jù)。
?
?
?
添加完數(shù)據(jù)后我們?cè)俜祷厝タ磾?shù)據(jù)庫(kù)中的變化。
?
?
?
?
如圖,數(shù)據(jù)庫(kù)中已經(jīng)保存了我們?cè)陧?yè)面上添加的數(shù)據(jù)。
到這里大家已經(jīng)看到了Code First 設(shè)計(jì)方式的大概過(guò)程?,F(xiàn)在我們來(lái)回顧一下,之前所做的操作,將會(huì)更加明白這一過(guò)程是怎樣進(jìn)行的,特別是代碼優(yōu)先是如何做到在沒(méi)有數(shù)據(jù)庫(kù)支持的情況下先建立數(shù)據(jù)模型,然后再對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作的。
首先我們?cè)贛odels中創(chuàng)建了所需要的數(shù)據(jù)模型Blog類,里面包含的字段將映射到以后數(shù)據(jù)庫(kù)表中的相應(yīng)列。
接下來(lái)同樣是在Models文件夾中,我們定義了一個(gè)最關(guān)鍵的BlogEntities上下文類,它繼承自System.Data.Entity下的DbContext,它將我們的數(shù)據(jù)模型映射到數(shù)據(jù)庫(kù)中,將代碼中的數(shù)據(jù)持久化。
最后,在頁(yè)面上進(jìn)行添加數(shù)據(jù)時(shí),頁(yè)面將表單數(shù)據(jù)通過(guò)Blog類型傳回Controller里面相應(yīng)的方法,這里是處理Post回傳的Create Action,它接收傳回來(lái)的數(shù)據(jù),通過(guò)調(diào)用db.SaveChanges()進(jìn)行了數(shù)據(jù)的保存。這里db是BlogEntities上下文類的一個(gè)實(shí)例。通過(guò)BlogEntities上下文類,我們進(jìn)行的RUD操作將反應(yīng)到數(shù)據(jù)庫(kù)中,完成了從代碼到數(shù)據(jù)庫(kù)的更新過(guò)程。
?
Data Annotations
接著上面的例子,試想,一篇博客一般還包含有分類信息,比如日志,隨筆等?,F(xiàn)在我們就去添加這樣一個(gè)類,保存博客的分類信息,相應(yīng)地,我們還應(yīng)更新一下我們的博客類,讓它包含一個(gè)分類屬性,這樣我們就可以指定一篇博客的所屬分類了。
這里將看到如何通過(guò)Code First創(chuàng)建表間的外鍵關(guān)系約束,以及定義表中列的其他信息,比如顯示的信息,
我們?cè)贛odels文件夾中繼續(xù)添加一個(gè)名為Category的類,它包含一個(gè)分類標(biāo)識(shí)屬性CategoryId, 一個(gè)分類名屬性CategoryName。代碼如下:
1 namespace MvcBlog.Models2 3 {4 5 public class Category6 7 {8 9 public int CategoryId { get; set; } 10 11 public string CategoryName { get; set; } 12 13 } 14 15 }?
更新Blog類:
1 namespace MvcBlog.Models2 3 {4 5 public class Blog6 7 {8 9 public int BlogId { get; set; } 10 11 public string Title { get; set; } 12 13 public DateTime CreateDate { get; set; } 14 15 public int CategoryId { get; set; } 16 17 } 18 19 }?
我們向其中添加了一個(gè)CategoryId屬性,下面設(shè)置它為引用自Category中CategoryId的外鍵。
這里有兩個(gè)方法Data Annotation 和 Fluent API用于實(shí)現(xiàn)這種到數(shù)據(jù)庫(kù)的映射,這里只討論Data Annotation。
由于CategoryId將會(huì)成為Blog到Category的導(dǎo)航屬性,所以,除了要在Blog中添加CategoryId外,還需要添加一個(gè)類型為Category的屬性,這樣,在Blog中才會(huì)有一個(gè)來(lái)自Category中CategoryId的聲明。
1 public class Blog2 3 {4 5 public int BlogId { get; set; }6 7 public string Title { get; set; }8 9 public DateTime CreateDate { get; set; } 10 11 public int CategoryId { get; set; } 12 13 public Category Category { get; set; } 14 15 }?
?
在使用Data Annotation添加外鍵屬性前需要添加System.ComponentModel.DataAnnotations命名空間到Blog類。然后我們就可以在CategoryId上面添加一個(gè)外鍵屬性了。更改后的代碼如下 :
public class Blog{public int BlogId { get; set; }public string Title { get; set; }public DateTime CreateDate { get; set; }[ForeignKey("CategoryId")]public int CategoryId { get; set; }public Category Category { get; set; }}?
同時(shí)更新我們的BlogEntities對(duì)象:
1 public class BlogEntities:DbContext 2 3 { 4 5 public DbSet<Blog> Blogs { get; set; } 6 7 public Category Categories { get; set; } 8 9 }?
?
這時(shí)當(dāng)我們運(yùn)行程序時(shí),會(huì)報(bào)錯(cuò),如圖:
?
?
因?yàn)橹斑\(yùn)行程序時(shí)已經(jīng)創(chuàng)建了數(shù)據(jù)庫(kù)了,而現(xiàn)在我們?cè)趯?duì)模型進(jìn)行更改后,它無(wú)法完全將更改之后的模型映射到之前的數(shù)據(jù)庫(kù),所以會(huì)出錯(cuò)。從錯(cuò)誤提示中已經(jīng)給出了解決辦法。要么手動(dòng)刪除之前創(chuàng)建好的數(shù)據(jù)庫(kù),要么使用DropCreateDatabaseIfModelChanges 的一個(gè)實(shí)例來(lái)對(duì)數(shù)據(jù)庫(kù)進(jìn)行初始化。需要注意的一點(diǎn)是,在商業(yè)開(kāi)發(fā)中,第二種方法要小心使用,因?yàn)樗鼤?huì)把之前的數(shù)據(jù)庫(kù)自動(dòng)刪掉重新創(chuàng)建,而如果你之前保存有大量信息在里面的話將無(wú)法挽回。
這里我們不想每次在修改模型之后都手動(dòng)去刪除,所以用第二種方法將十分簡(jiǎn)便,只需到Global.asax文件的Application_Start()方法里面添加如下一行即可。
1 protected void Application_Start()2 3 {4 5 Database.SetInitializer(new DropCreateDatabaseIfModelChanges<BlogEntities>());6 7 AreaRegistration.RegisterAllAreas();8 9 10 11 RegisterGlobalFilters(GlobalFilters.Filters); 12 13 RegisterRoutes(RouteTable.Routes); 14 15 }?
這樣,模型改變之后,它會(huì)刪除掉原來(lái)的數(shù)據(jù)庫(kù)重新創(chuàng)建。
?
我們?cè)俅芜\(yùn)行程序,然后再去數(shù)據(jù)庫(kù)看,第二張表Category已經(jīng)添加進(jìn)去了,并且在Blog表里面,也出現(xiàn)了一個(gè)CategoryId外鍵,正如我們所想要的那樣。
?
?
需要注意的地方
一個(gè)就是性能問(wèn)題,使用edm designer從數(shù)據(jù)庫(kù)來(lái)生成的ObjectContext,它會(huì)把很多東西存在CSDL,MSL,SSDL文件里,比如一些mapping信息,當(dāng)頁(yè)面load時(shí)需要先從EDM文件里來(lái)load這些metadata,而使用Code-first是從Assembly里load數(shù)據(jù),這樣應(yīng)該會(huì)節(jié)省不少時(shí)間。但另一方面,EF自動(dòng)生成的CONTEXT實(shí)體類會(huì)附帶很多冗余信息,使得文件相對(duì)臃腫,在讀取實(shí)體類中的信息時(shí)會(huì)在搜索上耗費(fèi)不必需的時(shí)間。關(guān)于性能問(wèn)題具體可閱讀一下參考中的第一篇文章。
另外就是現(xiàn)在Code First應(yīng)用得不是很多,就現(xiàn)在學(xué)習(xí)中碰到的例子來(lái)看,大部分都是Database First方式的。由于這是伴隨微軟新一代的EF4.1推出的設(shè)計(jì)方式,必定有其優(yōu)越性,所以以后的項(xiàng)目中還是可以嘗試用這種方式來(lái)進(jìn)行設(shè)計(jì)。
后記
我也是初學(xué)者,研究得不是很深刻,借鑒了許多別人的經(jīng)驗(yàn)與分享,再加上自己的創(chuàng)新理解,肯定有不恬當(dāng)?shù)牡胤?#xff0c;權(quán)當(dāng)加深自己的理解,與大家共同學(xué)習(xí)。
可以參考的一些文章
1.WCF和Entity framework 發(fā)現(xiàn)的性能問(wèn)題
http://www.cnblogs.com/GaryChen/archive/2010/02/06/1664912.html
2.Entity Framework 4中的Code-First, Model-First和Database-First模式
http://www.cnblogs.com/n-pei/archive/2010/08/12/1797751.html
3.Code-First Development with Entity Framework 4
http://weblogs.asp.net/scottgu/archive/2010/07/16/code-first-development-with-entity-framework-4.aspx
4.ADO.NET Entity Framework
http://en.wikipedia.org/wiki/ADO.NET_Entity_Framework
5.A Code First Example using Entity Framework 4
http://chris.widdowson.id.au/?p=746#
6. Entity Framework At-a-Glance
http://msdn.microsoft.com/en-us/data/aa937709
7. Nadege Deroussen在codeproject的三篇文章
Entity Framework Code First: Let's Try It
http://www.codeproject.com/Articles/318010/Entity-Framework-Code-First-Let-s-Try-It
EF Code First: Add a Foreign Key relationship
http://www.codeproject.com/Articles/319366/EF-Code-First-Add-a-Foreign-Key-relationship
EF Data Annotations and Code Fluent
http://www.codeproject.com/Articles/368164/EF-Data-Annotations-and-Code-Fluent
?
?CC BY-NC-SA 署名-非商業(yè)性使用-相同方式共享
分類:?MVC
標(biāo)簽:?Code First,?Data Annotations,?Entity Framework
好文要頂?關(guān)注我?收藏該文??
劉哇勇
關(guān)注 - 11
粉絲 - 2723
推薦博客
+加關(guān)注
??上一篇:?如何制作好一個(gè)提交按扭---我是個(gè)愛(ài)折騰的人
??下一篇:?關(guān)于jQuery UI 使用心得及技巧
posted @?2012-09-20 18:58??劉哇勇? 閱讀(50711)? 評(píng)論(49)??編輯??收藏
?
評(píng)論列表
??
#1樓?2012-09-20 20:43?玉菜園
收藏
支持(0)?反對(duì)(0)
??
#2樓?2012-09-20 21:24?niky
講的很基礎(chǔ)同時(shí)也很到位!園子里相關(guān)的Entity Framework文章也挺豐富的!!!
支持(0)?反對(duì)(0)
??
#3樓?2012-09-20 22:49?zhangzhigang
寫(xiě)的灰常好
支持(0)?反對(duì)(0)
??
#4樓?2012-09-20 23:49?LiangCheng
寫(xiě)的很好,我剛剛聊了了EF但還不夠深入,樓主收藏了
支持(0)?反對(duì)(0)
??
#5樓?2012-09-21 07:28?Kencery
學(xué)習(xí)了,謝謝樓主!
支持(0)?反對(duì)(0)
??
#6樓?2012-09-21 09:03?Y2zz
樓主辛苦了
支持(0)?反對(duì)(0)
??
#7樓?2012-09-21 09:05?騎馬找驢
不錯(cuò)!基礎(chǔ)通俗,頂
支持(0)?反對(duì)(0)
??
#8樓?2012-09-21 10:37?勵(lì)箭
通俗易懂,頂
支持(0)?反對(duì)(0)
??
#9樓?2012-09-21 12:28?幻天芒
這是一篇好文呀,通俗易懂。
支持(0)?反對(duì)(0)
??
#10樓?2012-12-04 16:07?nickycookie
寫(xiě)的很清楚,EF還可以用Nuget下載,我也經(jīng)常寫(xiě)一些工作中碰到問(wèn)題后總結(jié)性的文章,樓主可以看下。
namespace MvcBlog.Models
{
public class Blog
{
public int BlogId { get; set; }
public string Title { get; set; }
public DateTime CreateDate { get; set; }
[ForeignKey("CategoryId")]
public int CategoryId { get; set; }
//這里是不是漏了public Category Category { get; set; }
}
}
不過(guò)說(shuō)真的,我始終覺(jué)得再放一個(gè)CategoryId很怪,還是不太喜歡用EF,無(wú)論哪種模式
支持(0)?反對(duì)(0)
??
#11樓?2012-12-20 16:53?wuanju . com
最近想用,可看了感覺(jué)不如Nhibernate
支持(0)?反對(duì)(0)
??
#12樓?2013-01-19 18:20?風(fēng)云
不錯(cuò),正準(zhǔn)備把自動(dòng)建表的功能移植到ELinq中,呵呵
支持(0)?反對(duì)(0)
??
#13樓?2013-02-20 10:39?saiko
寫(xiě)的灰常好
支持(0)?反對(duì)(0)
??
#14樓?[樓主]?2013-05-13 22:54?劉哇勇@?nickycookie
引用寫(xiě)的很清楚,EF還可以用Nuget下載,我也經(jīng)常寫(xiě)一些工作中碰到問(wèn)題后總結(jié)性的文章,樓主可以看下。namespace MvcBlog.Models
{
public class Blog
{
public int BlogId { get; set; }
public string Title { get; set; }
public DateTime CreateDate { get; set; }
[ForeignKey("CategoryId")]
...
哎瑪,還真的是少了句代碼~
支持(0)?反對(duì)(0)
??
#15樓?2013-05-23 11:01?魔女小溪
之前看過(guò)entityframework,但是,始終都不明白什么意思,到現(xiàn)在還不不懂,呵呵,樓主寫(xiě)的確實(shí)非常詳細(xì),頂,滅哈哈哈
支持(0)?反對(duì)(0)
??
#16樓?2013-05-27 11:07?kiddy-star
首先,肯定文章寫(xiě)得很好,通俗易懂。個(gè)人的收獲是Code First方式在數(shù)據(jù)表變更的時(shí)候很麻煩,實(shí)際又退化到Database First,不可能為了修改一個(gè)字段就去刪除整個(gè)數(shù)據(jù)庫(kù),不過(guò)可能Code First有利有弊的考慮吧,只是在設(shè)計(jì)的時(shí)候用。
支持(0)?反對(duì)(0)
??
#17樓?2013-05-29 22:42?最佳損友。
study 慢慢看
支持(0)?反對(duì)(0)
??
#18樓?2014-04-29 10:21?魔女小溪
Lz,為啥我生成controller后,EntityState,這個(gè)報(bào)錯(cuò),說(shuō)上下文不存在
支持(0)?反對(duì)(0)
??
#19樓?2014-04-30 10:57?魔女小溪
LZ,你回我一下呀?為啥我總是出現(xiàn)這樣的錯(cuò)誤,不能夠創(chuàng)建成功數(shù)據(jù)庫(kù),報(bào)錯(cuò):在與 SQL Server 建立連接時(shí)出現(xiàn)與網(wǎng)絡(luò)相關(guān)的或特定于實(shí)例的錯(cuò)誤。未找到或無(wú)法訪問(wèn)服務(wù)器。請(qǐng)驗(yàn)證實(shí)例名稱是否正確并且 SQL Server 已配置為允許遠(yuǎn)程連接。 (provider: SQL Network Interfaces, error: 26 - 定位指定的服務(wù)器/實(shí)例時(shí)出錯(cuò))
支持(0)?反對(duì)(0)
??
#20樓?2014-04-30 11:23?魔女小溪
已經(jīng)解決了創(chuàng)建數(shù)據(jù)庫(kù)不成功這個(gè)問(wèn)題了,但是,這個(gè)問(wèn)題沒(méi)有解決,樓主,你在木有呀,為啥我生成controller后,EntityState,這個(gè)報(bào)錯(cuò),說(shuō)上下文不存在
支持(0)?反對(duì)(0)
??
#21樓?2014-04-30 14:54?魔女小溪
LZ,還有個(gè)問(wèn)題呀,我加一張相關(guān)聯(lián)的表,不是你上面說(shuō)的那種錯(cuò)誤,而是出現(xiàn)另外一種錯(cuò)誤,“The navigation property 'ClassId' is not a declared property on type 'SightPoint'. Verify that it has not been explicitly excluded from the model and that it is a valid navigation property.” 咋回事呀?你怎么不來(lái)逛園子呀!
支持(3)?反對(duì)(0)
??
#22樓?[樓主]?2014-05-02 08:41?劉哇勇
已解決~,勤奮的孩子@魔女小溪
支持(0)?反對(duì)(0)
??
#23樓?2014-05-04 10:30?魔女小溪
樓主,對(duì)于那個(gè)生成EntityState那個(gè),我用mvc3,確實(shí)沒(méi)錯(cuò),這個(gè)問(wèn)題是解決了,但是,還有一個(gè)問(wèn)題沒(méi)解決,就是那個(gè)添加關(guān)聯(lián)表的時(shí)候,添加不成功,出錯(cuò):
導(dǎo)航屬性“ClassId”不是類型“SightPoint”的已聲明屬性。請(qǐng)驗(yàn)證該屬性未從模型中顯式排除并且是有效的導(dǎo)航屬性。
global文件中我已經(jīng)加了
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<TourEntities>());,還是報(bào)這樣的錯(cuò)誤
支持(0)?反對(duì)(0)
??
#24樓?2014-06-03 11:32?hnxiangjiansheng
好文章
支持(0)?反對(duì)(0)
??
#25樓?2014-06-07 09:48?隨風(fēng)吹
樓主,我在按著你這個(gè)走的時(shí)候也遇到21樓的問(wèn)題
The navigation property 'ClassId' is not a declared property on type 'SightPoint'. Verify that it has not been explicitly excluded from the model and that it is a valid navigation property
google了一下,貌似是依賴出現(xiàn)了問(wèn)題,但是還是改不對(duì),還請(qǐng)樓主賜教!謝謝了
支持(0)?反對(duì)(0)
??
#26樓?2014-06-07 09:50?隨風(fēng)吹@?魔女小溪
引用LZ,還有個(gè)問(wèn)題呀,我加一張相關(guān)聯(lián)的表,不是你上面說(shuō)的那種錯(cuò)誤,而是出現(xiàn)另外一種錯(cuò)誤,“The navigation property 'ClassId' is not a declared property on type 'SightPoint'. Verify that it has not been explicitly excluded from the model and that it is a valid navigation property.” 咋回事呀?你怎么不來(lái)逛園子呀!
請(qǐng)問(wèn)你這個(gè)解決了嗎?還請(qǐng)賜教,說(shuō)明一下什么原因
支持(0)?反對(duì)(0)
??
#27樓?2014-06-07 10:05?隨風(fēng)吹額,google后改了
| 1 2 3 4 5 6 7 8 9 10 | public?class?Blog ????{ ????????public?int?BlogId {?get;?set; } ????????public?string?Title {?get;?set; } ????????public?DateTime CreateDate {?get;?set; } ????????[ForeignKey("Category")] ????????public?int?CategoryId {?get;?set; }//nav ? ????????public?virtual?Category Category {?get;?set; } ????} |
可以成功運(yùn)行,但是后部原因還是有點(diǎn)迷糊
支持(1)?反對(duì)(0)
??
#28樓?2014-07-03 13:41?魔女小溪
@?隨風(fēng)吹
還是不行呀?你另外一個(gè)類是怎么寫(xiě)的呢?
支持(0)?反對(duì)(0)
??
#29樓?2014-08-04 22:16?KennyZhao
寫(xiě)的不錯(cuò),剛剛開(kāi)始學(xué)習(xí)
支持(0)?反對(duì)(0)
??
#30樓?2014-09-14 20:59?學(xué)易不易
文中生成外鍵的方式有誤,正確添加外鍵的方法可以參考下面這篇文章:
http://www.cnblogs.com/jes_shaw/archive/2013/03/06/2946061.html
支持(0)?反對(duì)(0)
??
#31樓?2014-10-16 15:50?郭衛(wèi)東
收獲很多,寫(xiě)的很不錯(cuò)
支持(0)?反對(duì)(0)
??
#32樓?2014-12-05 14:00?學(xué)亮
DBFirst真的不好嗎?
支持(0)?反對(duì)(0)
??
#33樓?2015-01-28 23:52?鄭志成
樓主,辛苦了,我收藏了哦
支持(0)?反對(duì)(0)
??
#34樓?2015-01-30 10:57?端木非
樓主 你寫(xiě)ForeignKey的時(shí)候 多了一個(gè)Id,害我報(bào)錯(cuò):找不到元數(shù)據(jù) 希望樓主有空改改 不然很多人都會(huì)浪費(fèi)很多時(shí)間!!!
[ForeignKey( "Category" )]
public int CategoryId { get; set; }
public Category Category { get; set; }
支持(0)?反對(duì)(0)
??
#35樓?2015-03-25 16:12?津沅
樓主 我按照你的 試著做了一下,在添加控制器的時(shí)候提示這個(gè)是什么原因,能否給解釋一下。
支持(0)?反對(duì)(0)
??
#36樓?2015-04-05 13:09?清水圓柏
寫(xiě)的很詳細(xì),向您學(xué)習(xí)了。
支持(0)?反對(duì)(0)
??
#37樓?2015-05-18 16:31?0風(fēng)隨我動(dòng)0
樓主,辛苦了,我收藏了哦
支持(0)?反對(duì)(0)
??
#38樓?2015-06-08 13:00?—阿輝
不錯(cuò),大牛
支持(0)?反對(duì)(0)
??
#39樓?2015-06-11 16:38?AcherBoy、Chenjw
樓主、求改一下、依舊有問(wèn)題
支持(0)?反對(duì)(0)
??
#40樓?2015-06-11 16:39?AcherBoy、Chenjw
INSERT 語(yǔ)句與 FOREIGN KEY 約束"FK_dbo.Blogs_dbo.Categories_CategoryId"沖突。該沖突發(fā)生于數(shù)據(jù)庫(kù)"MvcBlog.Models.BlogEntities",表"dbo.Categories", column 'CategoryId'。
語(yǔ)句已終止。
說(shuō)明: 執(zhí)行當(dāng)前 Web 請(qǐng)求期間,出現(xiàn)未經(jīng)處理的異常。請(qǐng)檢查堆棧跟蹤信息,以了解有關(guān)該錯(cuò)誤以及代碼中導(dǎo)致錯(cuò)誤的出處的詳細(xì)信息。
異常詳細(xì)信息: System.Data.SqlClient.SqlException: INSERT 語(yǔ)句與 FOREIGN KEY 約束"FK_dbo.Blogs_dbo.Categories_CategoryId"沖突。該沖突發(fā)生于數(shù)據(jù)庫(kù)"MvcBlog.Models.BlogEntities",表"dbo.Categories", column 'CategoryId'。
語(yǔ)句已終止。
支持(0)?反對(duì)(0)
??
#41樓?2015-06-25 11:57?小小中
學(xué)習(xí)了
支持(0)?反對(duì)(0)
??
#42樓?2015-07-13 09:57?thhhhhhea
請(qǐng)問(wèn)為什么創(chuàng)建blogentity的時(shí)候,blog是dbset,而category就只是category了?
支持(0)?反對(duì)(0)
??
#43樓?2015-10-08 15:40?寢室長(zhǎng)
34樓正解,重新編譯后可解決35樓的問(wèn)題
支持(0)?反對(duì)(0)
??
#44樓?2015-10-26 11:25?fren
感謝樓主分享
支持(0)?反對(duì)(0)
??
#45樓?2015-12-22 09:51?kiaser
樓主你那個(gè)MvcBlog.Models.BlogEntities的數(shù)據(jù)庫(kù)生成的時(shí)候,webconfig的connectionString是怎么寫(xiě)的
支持(0)?反對(duì)(0)
??
#46樓?2016-07-08 11:04?2604529
mark
支持(0)?反對(duì)(0)
??
#47樓?2016-08-26 18:05?cnfanhua
那么問(wèn)題來(lái)了,如果不使用DropCreateDatabaseIfModelChanges ,model中新增個(gè)屬性 怎么辦
支持(0)?反對(duì)(0)
??
#48樓?2017-05-09 22:48?Leelom
不錯(cuò),必須操作到數(shù)據(jù)的時(shí)候才會(huì)觸發(fā)生成表,比如“登錄”、“顯示”,不管是增刪改查,任意一個(gè)操作“▲之后”才會(huì)生成表,否則不會(huì)生成。折騰半天。
支持(0)?反對(duì)(0)
??
#49樓?2019-03-13 17:02?學(xué)會(huì)樂(lè)觀
@?AcherBoy、Chenjw
我和你遇到同樣的問(wèn)題
總結(jié)
以上是生活随笔為你收集整理的【转】学习Entity Framework 中的Code First的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 白户能办高额信用卡么 白户办高额信用卡方
- 下一篇: 01-单一职责原则(SPR)