EF 6 - Các lệnh chặn DB

Lệnh chặn cơ sở dữ liệu trong EF 6

Trong phần này, chúng ta sẽ học cách chặn các lệnh cơ sở dữ liệu được thực thi bởi DbContext trong EF 6 cơ sở dữ liệu-đầu tiên, cũng như cách tiếp cận mã-thứ nhất.

EF 6 cung cấp khả năng chặn ngữ cảnh bằng cách thực thi giao diện IDbCommandInterceptor. Giao diện IDbCommandInterceptor chứa các phương thức chặn một đối tượng của DbContext và cho phép bạn thực thi logic tùy chỉnh của mình trước hoặc sau khi ngữ cảnh thực hiện các lệnh hoặc truy vấn. DbContext thực thi các lệnh và truy vấn bằng cách sử dụng các phương thứccủa  ADO.NET như ExecuteNonQuery, ExecuteScalar ExecuteReader, mà bạn có thể chặn bằng cách thực thi các phương thức như NonQueryExecuted NonQueryExecuting, v.v.

Để chặn một đối tượng của DbContext, trước tiên, hãy tạo lớp tùy chỉnh và thực thi IDbCommandInterceptor, Xem ví dụ sau:

class EFCommandInterceptor: IDbCommandInterceptor
{
    public void NonQueryExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
    {
        LogInfo("NonQueryExecuted", String.Format(" IsAsync: {0}, Command Text: {1}", interceptionContext.IsAsync, command.CommandText));
    }

    public void NonQueryExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<int> interceptionContext)
    {
        LogInfo("NonQueryExecuting", String.Format(" IsAsync: {0}, Command Text: {1}", interceptionContext.IsAsync,  command.CommandText));
    }

    public void ReaderExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<System.Data.Common.DbDataReader> interceptionContext)
    {
        LogInfo("ReaderExecuted", String.Format(" IsAsync: {0}, Command Text: {1}", interceptionContext.IsAsync, command.CommandText));
    }

    public void ReaderExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<System.Data.Common.DbDataReader> interceptionContext)
    {
        LogInfo("ReaderExecuting", String.Format(" IsAsync: {0}, Command Text: {1}", interceptionContext.IsAsync, command.CommandText));
    }

    public void ScalarExecuted(System.Data.Common.DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    {
        LogInfo("ScalarExecuted", String.Format(" IsAsync: {0}, Command Text: {1}", interceptionContext.IsAsync, command.CommandText));
    }

    public void ScalarExecuting(System.Data.Common.DbCommand command, DbCommandInterceptionContext<object> interceptionContext)
    {
        LogInfo("ScalarExecuting", String.Format(" IsAsync: {0}, Command Text: {1}", interceptionContext.IsAsync, command.CommandText));
    }

    private void LogInfo(string command, string commandText)
    {
        Console.WriteLine("Intercepted on: {0} :- {1} ", command, commandText);
    }
}

Trong ví dụ trên, IDbCommandInterceptor cung cấp sáu phương thức để thực thi. Nó ghi lại lệnh cho mục đích demo, nhưng chúng ta có thể viết logic tùy chỉnh của mình tại đây.

Tiếp theo, chúng ta sẽ cần phải định cấu hình bộ chặn bằng cách sử dụng tệp cấu hình hoặc cấu hình dựa trên mã nguồn.

Định cấu hình bộ chặn trong tệp app.config, như được hiển thị bên dưới:

<entityFramework>
    <interceptors>
        <interceptor type="EF6DBFirstTutorials.EFCommandInterceptor, EF6DBFirstTutorials">
        </interceptor>
    </interceptors>
</entityFramework>

Nếu chúng ta sử dụng cấu hình dựa trên mã nguồn.

public class FE6CodeConfig : DbConfiguration
{
    public FE6CodeConfig()
    {
        this.AddInterceptor(new EFCommandInterceptor());
    }
}

Vì vậy, bây giờ, chúng ta có thể lưu vết lệnh bất cứ khi nào một phiên bản DbContext thực thi một lệnh hoặc truy vấn. Hãy xem xét ví dụ sau.

var newStudent =  new Student() { FirstName = "Bill" };

using (var context = new SchoolDBEntities())
{
    context.Students.Add(newStudent);
    context.SaveChanges();
}

Kết quả:

Intercepted on: ReaderExecuting :- IsAsync: False, Command Text: INSERT [dbo].[Student]([FirstName], [StandardId], [LastName])
VALUES (@0, NULL, NULL)
SELECT [StudentID], [RowVersion] FROM [dbo].[Student]
WHERE @@ROWCOUNT > 0 AND [StudentID] = scope_identity()
Intercepted on: ReaderExecuted :- IsAsync: False, Command Text: INSERT [dbo].[Student]([FirstName], [StandardId], [LastName])
VALUES (@0, NULL, NULL)
SELECT [StudentID], [RowVersion] FROM [dbo].[Student]
WHERE @@ROWCOUNT > 0 AND [StudentID] = scope_identity()