設計工具 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 2012。
  • 選取 [檔案- > 新增 - 專案] >
  • 在左窗格中,按一下 [Visual C# ],然後選取 主控台 範本。
  • 輸入 CUDSProcsSample 作為名稱。
  • 選取 [確定]。

建立模型

  • 以滑鼠右鍵按一下方案總管中的專案名稱,然後選取 [ 新增 - > 新增專案 ]。

  • 從左側功能表中選取 [資料 ],然後在 [範本] 窗格中選取 [ADO.NET 實體資料模型 ]。

  • 輸入 CUDSProcs.edmx 以取得檔案名,然後按一下 [ 新增 ]。

  • 在 [選擇模型內容] 對話方塊中,選取 [從資料庫 產生],然後按 [下一步 ]。

  • 按一下 [ 新增連線。 在 [連線ion 屬性] 對話方塊中,輸入伺服器名稱 (例如 , localdb)\mssqllocaldb ),選取驗證方法,輸入 School 以取得資料庫名稱,然後按一下 [ 確定 ]。 [選擇您的資料連線] 對話方塊會使用您的資料庫連線設定來更新。

  • 在 [選擇資料庫物件] 對話方塊的 [資料表 ] 節點底下,選取 [ 人員 ] 資料表。

  • 此外,請選取 [預存程式和函式] 節點底下的 下列預存程式: DeletePerson、 InsertPerson UpdatePerson

  • 從 Visual Studio 2012 開始,EF Designer 支援大量匯入預存程式。 預設會檢查將 選取的預存程式和函式匯入至實體模型 。 由於在此範例中,我們有插入、更新和刪除實體類型的預存程式,因此我們不想匯入它們,而且會取消核取此核取方塊。

    Import S Procs

  • 按一下完成。 會顯示 EF 設計工具,其提供編輯模型的設計介面。

將 Person 實體對應至預存程式

  • 以滑鼠右鍵按一下 [ 人員 ] 實體類型,然後選取 [ 預存程式對應 ]。

  • 預存程式對應會出現在 [ 對應詳細 資料] 視窗中。

  • 按一下 [ < 選取插入函式 > ]。 此欄位會變成儲存模型中預存程序的下拉式清單,可以對應到概念模型中的實體類型。 從下拉式清單中選取 [InsertPerson ]。

  • 預存程序參數與實體屬性之間的預設對應隨即出現。 請注意,箭頭表示對應方向:為預存程序參數提供屬性值。

  • 按一下 [ < 新增結果系結 > ]。

  • 輸入 NewPersonID ,這是 InsertPerson 預存程式所 傳回的參數名稱。 請務必不要輸入前置或尾端空格。

  • Enter

  • 根據預設, NewPersonID 會對應至實體索引鍵 PersonID 。 請注意,箭頭表示對應方向:為屬性提供結果資料行的值。

    Mapping Details

  • 按一下 [ 選取更新函式 > ],然後從產生的下拉式清單中選取 [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 語句。

Debug With Intellitrace