天天看點

在Entity Framework中使用存儲過程(二):具有繼承關系實體的存儲過程如何定義?一、建立具有繼承關系的實體二、基于繼承關系實體的查詢與更新三、映射标準的CUD存儲過程四、修正存儲過程

目錄 一、建立具有繼承關系的實體 二、基于繼承關系實體的查詢與更新 三、映射标準的CUD存儲過程 四、修正存儲過程

假設資料庫中有如下兩個關聯的表:T_EMP和T_SALES。T_EMP用于存儲員工資訊,主鍵為代表員工ID号的EMP_ID。為了簡單起見,我僅僅定義兩個額外的字段:FIRST_NAME和LAST_NAME。另一個表T_EMP用于存儲銷售人員的資訊,它具有一樣的主鍵EMP_ID,額外的兩個字段代表負責的區域(Territory)和提成的比率(Commission

Rate)。兩者通過EMP_ID進行關聯。

<a href="http://images.cnblogs.com/cnblogs_com/artech/201103/201103062232174475.png"></a>

然後我們通過選擇這兩個表建立.edmx模型。由于這兩個表之間具有關聯,.edmx模型得兩個實體之間會預設建立聯系,你首先需要删除此聯系。由于銷售人員也是公司的員工,它屬于是員工類型的子類。是以你需要建立它們之間的繼承關系。由于具有繼承關系的兩個實體不能有重複的屬性,屬于你需要删除掉T_SALES的EMP_ID屬性。最後你需要修正實體和屬性的名稱使之更具可讀性。最後的.edmx模型如下圖所示。

<a href="http://images.cnblogs.com/cnblogs_com/artech/201103/201103062232185870.png"></a>

在引入存儲過程之前,我們先來談談針對于如上一個具有繼承關系實體的.edmx模型,如果進行查詢和更新。使用過EF的讀者應該很清楚,用戶端代碼進行資料的查詢和更新都是通過自動生成的一個繼承自ObjectContext的類來完成的。我們不妨來看看針對上面建立的.edmx模型,這個類具有怎樣的定義。由于我為該模型的Entity

Container起名為HrEntities,随後最終生成的是如下一個同名的類。

我們可以看到,雖然在模型中有兩個實體,但是對于HrEntities來說,它僅僅具有一個類型為ObjectSet&lt;Employee&gt;的Employees屬性(沒有ObjectSet&lt;Sales&gt;類型的屬性)和對應的AddToEmployee方法。但是針對這個兩個實體對應的類都是存在的,并且存在繼承關系。了解起來也容易,Sales也是Employee,是以Employees屬性表述的ObjectSet可以同時包括普通的Employee和Sales。

最後我們在一個控制台應用中編寫如下一段代碼。這段代碼中,先删除掉現有的Employee(包括Sales)記錄,然後分别添加一個Employee對象和Sales對象。最後通過查詢確定它被成功送出到資料庫中。

下面是我們希望的輸出結果:

從上面的代碼中我們可以看到,當我們通過ObjectContext添加一個Employee對象的時候,它會先根據對象的真實類型,判斷僅僅需要添加Employee對應的資料表記錄,還是需要同時在Employee和Sales對應的兩張資料表中同時添加一條記錄。修改和删除操作采用的機制也是如此。

下面三個是基于T_SALES資料表的三個存儲過程。

完成存儲過程的映射後,再次運作上面的代碼,會有如下一個UpdateException異常抛出來。追蹤InnerException,你會發現一條有用的異常消息:The

INSERT statement conflicted with the FOREIGN KEY constraint

"FK_T_SALES_T_EMP". The conflict occurred in database "EFExtensions",

table "dbo.T_EMP", column 'EMP_ID'.The statement has been terminated.

<a href="http://images.cnblogs.com/cnblogs_com/artech/201103/201103062232181867.png"></a>

之是以出現上述的異常在于:當我們添加一個Sale對象的時候,隻有Sales實體對象的Insert存儲過程被執行。而該存儲過程僅僅是為T_SALES資料表中插入資料,但是此時主表T_EMP沒有相應的記錄,違反外鍵限制。在進行資料的修改和删除時,也有相同的問題。

為了解決這個問題,我們隻需要修改子類對應表的存儲過程,讓它們同時去添加、修改和删除主記錄。下面列出了修正後的存儲過程定義。

P_SALES_I

P_SALES_U

P_SALES_D

然後在EF的模型設計器中對新的參數進行映射即可。

<a href="http://www.cnblogs.com/artech/archive/2011/03/05/stored_procedure_mapping.html">在Entity Framework中使用存儲過程(一):實作存儲過程的自動映射</a>

<a href="http://www.cnblogs.com/artech/archive/2011/03/06/stored_procedure_inheritance.html">在Entity Framework中使用存儲過程(二):具有繼承關系實體的存儲過程如何定義?</a>

<a href="http://www.cnblogs.com/artech/archive/2011/03/13/logical_delete.html">在Entity Framework中使用存儲過程(三):邏輯删除的實作與自增長列值傳回</a>

<a href="http://www.cnblogs.com/artech/archive/2011/03/13/procedure_mapping_version.html">在Entity Framework中使用存儲過程(四):如何為Delete存儲過程參數賦上Current值?</a>

<a href="http://www.cnblogs.com/artech/archive/2011/03/16/1986202.html">在Entity Framework中使用存儲過程(五):如何通過存儲過程維護多對多關系?</a>

作者:蔣金楠

微信公衆賬号:大内老A

如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識别二維碼)關注個人公衆号(原來公衆帳号蔣金楠的自媒體将會停用)。

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。

<a href="http://www.cnblogs.com/artech/archive/2011/03/06/stored_procedure_inheritance.html" target="_blank">原文連結</a>