設計工具 CUD 預存程式
這個逐步解說示範如何使用 Entity Framework Designer (EF Designer) 將實體類型的 create\insert、update 和 delete (CUD) 作業對應至預存程式。 根據預設,Entity Framework 會自動產生 CUD 作業的 SQL 語句,但您也可以將預存程式對應至這些作業。
請注意,Code First 不支援對應至預存程式或函式。 不過,您可以使用 System.Data.Entity.DbSet.SqlQuery 方法呼叫預存程式或函式。 例如:
var query = context.Products.SqlQuery("EXECUTE [dbo].[GetAllProducts]");
將 CUD 作業對應至預存程式時的考慮
將 CUD 作業對應至預存程式時,適用下列考慮:
- 如果您要將其中一個 CUD 作業對應至預存程式,請對應所有作業。 如果您未對應這三個作業,則執行時未對應的作業將會失敗,而且 會擲回 UpdateException 。
- 您必須將預存程式的每個參數對應至實體屬性。
- 如果伺服器為插入的資料列產生主鍵值,您必須將此值對應回實體的索引鍵屬性。 在後續範例中, InsertPerson 預存程式會傳回新建立的主鍵做為預存程式結果集的一部分。 主鍵會使用 < EF 設計工具的 [新增結果系結 > ] 功能,對應至實體索引鍵 ( PersonID )。
- 預存程式呼叫會與概念模型中的實體對應 1:1。 例如,如果您在概念模型中實作繼承階層,然後對應 Parent (base) 和 Child (derived) 實體的 CUD 預存程式 ,儲存 Child 變更只會呼叫 Child 的預存程式,則不會觸發 Parent 的預存程式呼叫。
必要條件
若要完成這個逐步解說,您將需要:
- 最新版的 Visual Studio。
- School 範例資料庫 。
設定專案
- 開啟 Visual Studio 2012。
- 選取 [檔案- > 新增 - 專案] >
- 在左窗格中,按一下 [Visual C# ],然後選取 主控台 範本。
- 輸入 CUDSProcsSample 作為名稱。
- 選取 [確定]。
建立模型
以滑鼠右鍵按一下方案總管中的專案名稱,然後選取 [ 新增 - > 新增專案 ]。
從左側功能表中選取 [資料 ],然後在 [範本] 窗格中選取 [ADO.NET 實體資料模型 ]。
輸入 CUDSProcs.edmx 以取得檔案名,然後按一下 [ 新增 ]。
在 [選擇模型內容] 對話方塊中,選取 [從資料庫 產生],然後按 [下一步 ]。
按一下 [ 新增連線。 在 [連線ion 屬性] 對話方塊中,輸入伺服器名稱 (例如 , localdb)\mssqllocaldb ),選取驗證方法,輸入 School 以取得資料庫名稱,然後按一下 [ 確定 ]。 [選擇您的資料連線] 對話方塊會使用您的資料庫連線設定來更新。
在 [選擇資料庫物件] 對話方塊的 [資料表 ] 節點底下,選取 [ 人員 ] 資料表。
此外,請選取 [預存程式和函式] 節點底下的 下列預存程式: DeletePerson、 InsertPerson 和 UpdatePerson 。
從 Visual Studio 2012 開始,EF Designer 支援大量匯入預存程式。 預設會檢查將 選取的預存程式和函式匯入至實體模型 。 由於在此範例中,我們有插入、更新和刪除實體類型的預存程式,因此我們不想匯入它們,而且會取消核取此核取方塊。
按一下完成。 會顯示 EF 設計工具,其提供編輯模型的設計介面。
將 Person 實體對應至預存程式
以滑鼠右鍵按一下 [ 人員 ] 實體類型,然後選取 [ 預存程式對應 ]。
預存程式對應會出現在 [ 對應詳細 資料] 視窗中。
按一下 [ < 選取插入函式 > ]。 此欄位會變成儲存模型中預存程序的下拉式清單,可以對應到概念模型中的實體類型。 從下拉式清單中選取 [InsertPerson ]。
預存程序參數與實體屬性之間的預設對應隨即出現。 請注意,箭頭表示對應方向:為預存程序參數提供屬性值。
按一下 [ < 新增結果系結 > ]。
輸入 NewPersonID ,這是 InsertPerson 預存程式所 傳回的參數名稱。 請務必不要輸入前置或尾端空格。
按 Enter。
根據預設, NewPersonID 會對應至實體索引鍵 PersonID 。 請注意,箭頭表示對應方向:為屬性提供結果資料行的值。
按一下 [ 選取更新函式 > ],然後從產生的下拉式清單中選取 [UpdatePerson ]。 <
預存程序參數與實體屬性之間的預設對應隨即出現。
按一下 [ 選取刪除函式 > ],然後從產生的下拉式清單中選取 DeletePerson 。 <
預存程序參數與實體屬性之間的預設對應隨即出現。
Person 實體類型的插入、更新和刪除作業 現在會對應至預存程式。
如果您想要在更新或刪除具有預存程式的實體時啟用並行檢查,請使用下列其中一個選項:
- 使用 OUTPUT 參數從預存程式傳回受影響的資料列數目,並核取參數名稱旁邊的 [ 資料列受影響的參數 ] 核取方塊。 如果呼叫作業時傳回的值為零, 則會擲回 OptimisticConcurrencyException 。
- 核取您要用於並行檢查的屬性旁的 [ 使用原始值] 核取方塊。 嘗試更新時,當將資料寫回資料庫時,將會使用原本從資料庫讀取的屬性值。 如果值不符合資料庫中的值, 則會擲回 OptimisticConcurrencyException 。
使用模型
開啟定義 Main 方法的 Program.cs 檔案。 將下列程式碼新增至 Main 函式。
程式碼會建立新的 Person 物件,然後更新 物件,最後刪除物件。
using (var context = new SchoolEntities())
{
var newInstructor = new Person
{
FirstName = "Robyn",
LastName = "Martin",
HireDate = DateTime.Now,
Discriminator = "Instructor"
}
// Add the new object to the context.
context.People.Add(newInstructor);
Console.WriteLine("Added {0} {1} to the context.",
newInstructor.FirstName, newInstructor.LastName);
Console.WriteLine("Before SaveChanges, the PersonID is: {0}",
newInstructor.PersonID);
// SaveChanges will call the InsertPerson sproc.
// The PersonID property will be assigned the value
// returned by the sproc.
context.SaveChanges();
Console.WriteLine("After SaveChanges, the PersonID is: {0}",
newInstructor.PersonID);
// Modify the object and call SaveChanges.
// This time, the UpdatePerson will be called.
newInstructor.FirstName = "Rachel";
context.SaveChanges();
// Remove the object from the context and call SaveChanges.
// The DeletePerson sproc will be called.
context.People.Remove(newInstructor);
context.SaveChanges();
Person deletedInstructor = context.People.
Where(p => p.PersonID == newInstructor.PersonID).
FirstOrDefault();
if (deletedInstructor == null)
Console.WriteLine("A person with PersonID {0} was deleted.",
newInstructor.PersonID);
}
- 編譯並執行應用程式。 程式會產生下列輸出 *
注意
PersonID 是由伺服器自動產生,因此您很可能會看到不同的數位*
Added Robyn Martin to the context.
Before SaveChanges, the PersonID is: 0
After SaveChanges, the PersonID is: 51
A person with PersonID 51 was deleted.
如果您使用 Visual Studio 的 Ultimate 版本,您可以使用 Intellitrace 搭配偵錯工具來查看執行的 SQL 語句。