天天看點

Entity Framework 5.0系列之資料操作查詢增加删除修改

entity framework将概念模型中定義的實體和關系映射到資料源,利用實體架構可以将資料源傳回的資料具體化為對象;跟蹤對象所做的更改;并發處理;将對象更改傳播到資料源等。今天我們就一起讨論如何利用entity framework進行查詢、插入、更新和删除資料。

我們将使用adventureworks資料庫來進行今天的所有示範,是以開始之前請準備好相應的資料庫。在ef中進行查詢應該說是相當簡單,隻需要定義一個類繼承于“dbcontext”,然後定義對應的“dbset”集合屬性即可。例如下面的“adventureworkscontext”類:

一個資料庫上下文的生命周期随着該對象的建立而開始,随着對象的釋放(或gc回收)而結束,是以建議在開發過程中使用“using”編碼方式,這樣就可以免去手動釋放對象的操作。如下面的代碼:

另外對于資料庫連接配接的管理在ef中是透明的,我們一般不需要手動進行處理,當查詢一個對象時打開連接配接當處理完查詢的結果集之後會自動關閉連接配接。

在ef的code first模式中有三種常用的資料查詢方式(model first和database first中還有其他方式如:使用entity sql,但這不是我們今天的重點):linq to entity表達式查詢、基于方法的查詢、原生sql查詢。

查詢表達式是c#3.0新增的功能,它是由一組類似于t-sql或xquery聲明性語句組成,clr并不能直接讀取這種查詢表達式而是在編譯時轉換為對應的方法調用。如下面的例子:

基于方法的查詢事實上是一組對象的擴充方法,同linq查詢不同的是這些方法可以直接被clr識别并運作。

例如上面的方法我們可以轉換為如下代碼,他們的效果是一樣的,傳回的都是“iqueryable”對象:

ef還支援原生sql查詢(注意與entity sql差別),例如:

不僅如此,ef還支援非實體類型的查詢:

當然也支援無傳回值的sql指令:

在ef中添加操作一般有兩種方式:一是直接建立對象,然後調用“dbset”的”add()”方法進行添加;二是調用資料庫上下文的”entry()”方法并設定對應的狀态。無論使用哪種方式最終一定要調用“savechange()”進行送出。如:

效果如圖:

Entity Framework 5.0系列之資料操作查詢增加删除修改

此外,在含有導航屬性時,将一個對象指派給另一個對象的導航屬性也能達到添加的效果(當導航屬性為”dbset“集合時通過調用導航屬性的“add()“方法也同樣可以達到添加效果),例如在”person.person”中我們上面添加了兩條記錄,但對于“person”類的導航屬性“emailaddress”和“password”在對應的“emailaddress”表和“password”表中并沒有添加對應的記錄,此時我們就可以通過下面的方式來增加:

此時檢視将可以看到“emailaddress”表中确實增加了一條記錄(“password”表同樣也是如此):

Entity Framework 5.0系列之資料操作查詢增加删除修改

在這裡我們需要強調一點那就是狀态跟蹤,對于上面的操作如果我們調用“attach()”方法對實體進行跟蹤或者設定實體的狀态那麼資料将不會儲存到資料庫:

使用”attach()”方法進行實體跟蹤時會設定實體的狀态為“unchanged”此時實體處于未修改狀态,當執行“savechange()”方法時ef不會執行修改操作。相反如果此時設定實體狀态為“modified”則ef執行更新操作。那麼既然ef的資料修改操作(增加、更新、删除)是根據實體狀态而進行的,那麼為什麼之前我們的增加操作能正常進行而不用手動修改其狀态呢?原因是ef會自動發現狀态改變,在調用下面的方法時狀态發現是自動的:

· dbset.find

· dbset.local

· dbset.remove

· dbset.add

· dbset.attach

· dbcontext.savechanges

· dbcontext.getvalidationerrors

· dbcontext.entry

· dbchangetracker.entries

當然,并不是所有的時候我們都需要ef自動發現狀态改變,設定 “dbcontext.configuration.autodetectchangesenabled”屬性為“false”可以禁用自動發現功能。

Entity Framework 5.0系列之資料操作查詢增加删除修改

注意:在ef對資料操作時有時會抛出: 

validation failed for one or more entities. see 'entityvalidationerrors' property for more details. 

此時可以使用try{} catch(dbentityvalidationexception ex){} 對異常進行捕獲,将滑鼠放到ex上并逐級檢視ex的資訊進行解決。

下面看一下ef的删除操作:

當然有了上面狀态跟蹤的讨論相信大家也可以想到如下删除方法:

修改資料很簡單,直接修改對應的屬性即可:

需要說明的是,ef在執行修改操作前會檢查哪些屬性發生了變化,并且隻會修改發生變化的字段。

今天的内容就先到這裡了,從前面的ef5.0概覽到現在的資料操作,關于ef5.0基礎的入門内容已經說完了,更多内容敬請關注後面的文章。

1

2

3

4

5

6

7

8

9

<code>- (</code><code>void</code><code>)</code><code>configdelegate</code> <code>{</code>

<code>    </code><code>__weak</code> <code>typeof</code><code>(</code><code>self</code><code>) </code><code>weakself</code> <code>= </code><code>self</code><code>;</code>

<code>    </code><code>[</code><code>self</code><code>.</code><code>delegate</code> <code>setselectrowatindexpathblock</code><code>:^(</code><code>id</code> <code>cell</code><code>, </code><code>nsindexpath</code> <code>*</code><code>indexpath</code><code>) {</code>

<code>      </code><code>tmpremierebrand</code> <code>*</code><code>premierebrand</code> <code>= (</code><code>tmpremierebrand</code> <code>*)</code><code>weakself</code><code>.</code><code>data</code><code>[</code><code>indexpath</code><code>.</code><code>row</code><code>];</code>

<code>      </code><code>tmspecialtopiccontroller</code> <code>*</code><code>specialtopiccontroller</code> <code>= [[</code><code>tmspecialtopiccontroller</code> <code>alloc</code><code>] </code><code>init</code><code>];</code>

<code>      </code><code>specialtopiccontroller</code><code>.</code><code>premierebrandid</code> <code>= </code><code>premierebrand</code><code>.</code><code>id</code><code>;</code>

<code>      </code><code>[</code><code>weakself</code><code>.</code><code>navigationcontroller</code> <code>pushviewcontroller</code><code>:</code><code>specialtopiccontroller</code> <code>animated</code><code>:</code><code>yes</code><code>];</code>

<code>    </code><code>}];</code>

<code>}</code>