EF Code-First - Sử dụng Stored Procedures

Sử dụng Stored Procedures trong Code First

Entity Framework 6 Code First cung cấp khả năng tạo và sử dụng stored procedure để thực hiện các thao tác thêm, cập nhật và xóa khi gọi phương thức SaveChanges().

Chúng ta hãy sử dụng các stored procedure cho các thao tác CUD (Create, Update, Delete) cho thực thể Student sau.

class Student
{
    public int StudentId { get; set; }
    public string StudentName { get; set; }
    public DateTime DoB { get; set; }
}

Sử dụng phương thức MapToStoredProcedures() để ánh xạ một thực thể với các stored procedure mặc định (các stored procedure mặc định này sẽ được tạo bởi EF API). Ví dụ sau ánh xạ thực thể Student với các stored procedure mặc định.

public class SchoolContext: DbContext 
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<Student>()
                    .MapToStoredProcedures();
    }

    public DbSet<Student> Students { get; set; }
}

EF API sẽ tạo ra ba stored procedure Student_Insert, Student_UpdateStudent_Delete cho thực thể Student ở trên, như hình dưới đây.

code first stored procedures

Các stored procedure Student_InsertStudent_Update có các tham số cho tất cả các thuộc tính của thực thể Student. Riêng stored procedure Student_Delete chỉ có một tham số cho thuộc tính khóa chính StudentId của thực thể Student. Sau đây là mã của các stored procedure.

CREATE PROCEDURE [dbo].[Student_Insert]
    @StudentName [nvarchar](max),
    @DoB [datetime]
AS
BEGIN
    INSERT [dbo].[Students]([StudentName], [DoB])
    VALUES (@StudentName, @DoB)
    
    DECLARE @StudentId int
    SELECT @StudentId = [StudentId]
    FROM [dbo].[Students]
    WHERE @@ROWCOUNT > 0 AND [StudentId] = scope_identity()
    
    SELECT t0.[StudentId]
    FROM [dbo].[Students] AS t0
    WHERE @@ROWCOUNT > 0 AND t0.[StudentId] = @StudentId
END

CREATE PROCEDURE [dbo].[Student_Update]
    @StudentId [int],
    @StudentName [nvarchar](max),
    @DoB [datetime]
AS
BEGIN
    UPDATE [dbo].[Students]
    SET [StudentName] = @StudentName, [DoB] = @DoB
    WHERE ([StudentId] = @StudentId)
END

CREATE PROCEDURE [dbo].[Student_Delete]
    @StudentId [int]
AS
BEGIN
    DELETE [dbo].[Students]
    WHERE ([StudentId] = @StudentId)
END

Ánh xạ Stored procedure tùy chỉnh cho một thực thể

EF 6 cho phép bạn sử dụng các stored procedure tùy chỉnh của riêng bạn và ánh xạ chúng tới một thực thể. Bạn cũng có thể cấu hình ánh xạ tham số với các thuộc tính của thực thể.

Ví dụ sau ánh xạ các stored procedure tùy chỉnh với thực thể Student.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Entity<Student>()
		.MapToStoredProcedures(p => p.Insert(sp => sp.HasName("sp_InsertStudent").Parameter(pm => pm.StudentName, "name").Result(rs => rs.StudentId, "Id"))
			.Update(sp => sp.HasName("sp_UpdateStudent").Parameter(pm => pm.StudentName, "name"))
			.Delete(sp => sp.HasName("sp_DeleteStudent").Parameter(pm => pm.StudentId, "Id"))
            );
}

Trong ví dụ trên, thực thể Student được ánh xạ tới các stored procedure sp_InsertStudent, sp_UpdateStudentsp_DeleteStudent. Nó cũng cấu hình ánh xạ giữa các tham số và thuộc tính của thực thể.

Sử dụng stored procedure cho tất cả các thực thể

Bạn có thể ánh xạ tất cả các thực thể của mình với các stored procedure mặc định trong một câu lệnh như dưới đây.

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    modelBuilder.Types().Configure(t => t.MapToStoredProcedures());
}

Khuyết điểm 

  • Chỉ có thể sử dụng Fluent API để ánh xạ các stored procedure. Không có attribute chú thích dữ liệu nào có sẵn trong EF 6 để ánh xạ stored procedure.
  • Bạn phải ánh xạ các stored procedure thêm, cập nhật và xóa cho một thực thể nếu bạn muốn sử dụng stored procedure cho các hoạt động CUD. Ánh xạ chỉ một trong số các thao tác CUD là không được phép.