Entity Framework入門教程(14)---DbFirst下的存儲過程

EF6中DbFirst模式下使用存儲過程

  咱們已經知道EF能夠將L2E或Entity SQL的查詢語句自動轉換成SQL命令,也能夠根據實體的狀態自動生成Insert/update/delete的Sql命令。這節介紹EF中使用預先定義的存儲過程對一張或者多種表進行CURD操做。html

  EF API會新建一個function來映射數據庫中的自定義函數或存儲過程。下邊講解EF DbFirst模式下存儲過程的用法,EF CodeFirst存儲過程的用法會在之後的EF CodeFirst系列中介紹。數據庫

1.DbFirst模式——使用存儲過程查詢數據

第一步 在數據庫新建存儲過程

首先在數據庫建立一個名爲GetCoursesByStudentId的存儲過程,這個存儲過程返回一個學生的全部課程。瀏覽器

CREATE PROCEDURE [dbo].[GetCoursesByStudentId]
    -- Add the parameters for the stored procedure here
    @StudentId int = null
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    -- Insert statements for procedure here
select c.courseid, c.coursename,c.Location, c.TeacherId
from student s 
left outer join studentcourse sc on sc.studentid = s.studentid 
left outer join course c on c.courseid = sc.courseid
where s.studentid = @StudentId
END

第二步 生成EMD

  這一步和普通生成EMD過程是同樣的,值得注意的是在Choose Your Database Objects and Settings這一步勾選咱們新建的存儲過程(GetCoursesByStudentId)和下邊的Import selected stored procedures and functions into the entity model ,以下圖所示app

GetCoursesByStudentId()返回Course實體集合,因此咱們不須要返回一個新的複雜類型。右鍵Function Imports下的GetCoursesByStudentId方法,選擇Edit,出現如下界面,把Entities設置爲Course便可函數

經過上邊兩步,在context中會生成一個GetCoursesByStudentId方法:post

如今咱們就能夠愉快地使用context.GetCoursesByStudentId來執行存儲過程了!以下:spa

using (var context = new SchoolDBEntities())
{
    var courses = context.GetCoursesByStudentId(1);

    foreach (Course cs in courses)
        Console.WriteLine(cs.CourseName);
}

在數據庫中執行的命令爲: exec [dbo].[GetCoursesByStudentId] @StudentId=1 設計

一點補充:EF中的表值函數和查詢的存儲過程使用的步驟是如出一轍的(表值函數和存儲過程原本就很相似,一個最重要的區別是EF中表值函數的返回值可用linq查詢過濾)3d

2.DbFirst模式——使用存儲過程執行CUD操做

這一部分介紹怎麼經過存儲過程來執行CUD(creat,update,delete)操做。code

咱們在數據庫添加如下幾個存儲:

Sp_InsertStudentInfo(添加):

CREATE PROCEDURE [dbo].[sp_InsertStudentInfo]
    -- Add the parameters for the stored procedure here
    @StandardId int = null,
    @StudentName varchar(50)
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

        INSERT INTO [SchoolDB].[dbo].[Student]([StudentName],[StandardId])
        VALUES(@StudentName, @StandardId)

    SELECT SCOPE_IDENTITY() AS StudentId

END

sp_UpdateStudent(修改):

CREATE PROCEDURE [dbo].[sp_UpdateStudent]
    -- Add the parameters for the stored procedure here
    @StudentId int,
    @StandardId int = null,
    @StudentName varchar(50)
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    Update [SchoolDB].[dbo].[Student] 
    set StudentName = @StudentName,StandardId = @StandardId
    where StudentID = @StudentId;

END

sp_DeleteStudent(刪除):

CREATE PROCEDURE [dbo].[sp_DeleteStudent]
    -- Add the parameters for the stored procedure here
    @StudentId int
AS
BEGIN
    -- SET NOCOUNT ON added to prevent extra result sets from
    -- interfering with SELECT statements.
    SET NOCOUNT ON;

    DELETE FROM [dbo].[Student]
    where StudentID = @StudentId

END
    

第一步:升級EDM

首先咱們要升級EDM把這些存儲過程添加當咱們的EDM中。右鍵設計器,選擇Update Model from Database,就出現了升級界面,以下圖所示,展開Stored Procedure and Functions,勾選咱們上邊建立的三個存儲過程,而後點擊Finish。

這時模型瀏覽器中在Store Model中有了這三個存儲過程,可是Function Imports中沒有,以下所示:

打開模型設計器在Student實體上右鍵,選擇Stored Procedure Mapping,來打開映射詳情界面,以下圖

在下面的映射詳細界面,咱們看到<Select Insert Function>, <Select Update Function>, and <Select Delete Function>,給這些下拉菜單分別選擇對應的存儲過程,同時選擇存儲過程的輸入輸出參數,以下圖所示:

右擊Student實體,選擇Validate,確保沒有錯誤

如今咱們執行add,update,或者delete時,EF再也不執行自動生成的SQL命令,而是經過這些存儲過程來執行,下面是一個栗子:

using (var context = new SchoolDBEntities())
{
    Student student = new Student() { StudentName = "New student using SP"};

    context.Students.Add(student);
    //執行 sp_InsertStudentInfo 
    context.SaveChanges();

    student.StudentName = "Edit student using SP";
    //執行 sp_UpdateStudent
    context.SaveChanges();

    context.Students.Remove(student);
    //執行 sp_DeleteStudentInfo 
    context.SaveChanges();
}

調用SaveChange()方法時,在數據庫中執行的命令以下:

exec [dbo].[sp_InsertStudentInfo] @StandardId=NULL,@StudentName='New student using SP'
go

exec [dbo].[sp_UpdateStudent] @StudentId=47,@StandardId=NULL,@StudentName='Edit student using SP'
go

exec [dbo].[sp_DeleteStudent] @StudentId=47
go

注意:不管是使用存儲過程仍是默認生成的Sql命令,當插入一條記錄並執行完SaveChange()方法後,這個新的實例會當即分配一個Id。這樣設計是爲了有效地追蹤實體,讓咱們能夠對實體執行進一步的操做(如沒有id執行update會拋出異常),以下圖:

 

EF系列目錄連接:Entity Franmework系列教程彙總

相關文章
相關標籤/搜索