EF Core 记录对数据的所有操作

318 阅读2分钟

为了使用 Entity Framework Core (EF Core) 记录用户对数据的所有操作 SQL 语句,你可以通过 EF Core 的拦截器来实现。拦截器可以捕获和记录发送到数据库的 SQL 命令。

以下是具体步骤:

1. 创建数据库上下文

首先,确保你有一个 EF Core 数据上下文和一个模型类。例如:

public class YourDbContext : DbContext
{
    public YourDbContext(DbContextOptions<YourDbContext> options) : base(options) { }

    public DbSet<YourModel> YourModels { get; set; }

    // 配置模型
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
    }
}

public class YourModel
{
    public int Id { get; set; }
    public string Name { get; set; }
    // 其他属性
}

2. 创建一个拦截器来捕获 SQL 语句

创建一个拦截器类来捕获并记录 SQL 语句:

using Microsoft.EntityFrameworkCore.Diagnostics;
using System.Diagnostics;
using System.Threading;
using System.Threading.Tasks;

public class SqlLoggingInterceptor : DbCommandInterceptor
{
    public override InterceptionResult<int> NonQueryExecuting(
        DbCommand command,
        CommandEventData eventData,
        InterceptionResult<int> result)
    {
        LogSql(command.CommandText);
        return base.NonQueryExecuting(command, eventData, result);
    }

    public override Task<InterceptionResult<int>> NonQueryExecutingAsync(
        DbCommand command,
        CommandEventData eventData,
        InterceptionResult<int> result,
        CancellationToken cancellationToken = default)
    {
        LogSql(command.CommandText);
        return base.NonQueryExecutingAsync(command, eventData, result, cancellationToken);
    }

    public override InterceptionResult<DbDataReader> ReaderExecuting(
        DbCommand command,
        CommandEventData eventData,
        InterceptionResult<DbDataReader> result)
    {
        LogSql(command.CommandText);
        return base.ReaderExecuting(command, eventData, result);
    }

    public override Task<InterceptionResult<DbDataReader>> ReaderExecutingAsync(
        DbCommand command,
        CommandEventData eventData,
        InterceptionResult<DbDataReader> result,
        CancellationToken cancellationToken = default)
    {
        LogSql(command.CommandText);
        return base.ReaderExecutingAsync(command, eventData, result, cancellationToken);
    }

    public override InterceptionResult<object> ScalarExecuting(
        DbCommand command,
        CommandEventData eventData,
        InterceptionResult<object> result)
    {
        LogSql(command.CommandText);
        return base.ScalarExecuting(command, eventData, result);
    }

    public override Task<InterceptionResult<object>> ScalarExecutingAsync(
        DbCommand command,
        CommandEventData eventData,
        InterceptionResult<object> result,
        CancellationToken cancellationToken = default)
    {
        LogSql(command.CommandText);
        return base.ScalarExecutingAsync(command, eventData, result, cancellationToken);
    }

    private void LogSql(string sql)
    {
        // 将 SQL 语句记录到你所需的位置,例如日志文件、数据库或控制台
        Debug.WriteLine(sql);
    }
}

3. 注册拦截器

YourDbContext 类中重写 OnConfiguring 方法,注册这个拦截器:

public class YourDbContext : DbContext
{
    public YourDbContext(DbContextOptions<YourDbContext> options) : base(options) { }

    public DbSet<YourModel> YourModels { get; set; }

    // 配置模型
    protected override void OnModelCreating(ModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
    }

    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.AddInterceptors(new SqlLoggingInterceptor());
        base.OnConfiguring(optionsBuilder);
    }
}

4. 配置 DI 容器

Startup.cs 文件中配置依赖注入容器:

public class Startup
{
    public IConfiguration Configuration { get; }

    public Startup(IConfiguration configuration)
    {
        Configuration = configuration;
    }

    public void ConfigureServices(IServiceCollection services)
    {
        services.AddDbContext<YourDbContext>(options =>
            options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))
        );

        // 其他服务配置
        services.AddControllersWithViews();
    }

    public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
    {
        if (env.IsDevelopment())
        {
            app.UseDeveloperExceptionPage();
        }
        else
        {
            app.UseExceptionHandler("/Home/Error");
            app.UseHsts();
        }

        app.UseHttpsRedirection();
        app.UseStaticFiles();
        app.UseRouting();
        app.UseAuthorization();

        app.UseEndpoints(endpoints =>
        {
            endpoints.MapControllerRoute(
                name: "default",
                pattern: "{controller=Home}/{action=Index}/{id?}");
        });
    }
}

5. 运行应用程序并查看日志

现在,当你在应用程序中对 YourDbContext 执行任何数据库操作时,SQL 语句将会通过 SqlLoggingInterceptor 被记录。你可以将这些日志输出到控制台、文件或其他存储系统,具体取决于你的需求。

通过上述步骤,你可以在 ASP.NET Core 应用程序中使用 EF Core 拦截器记录所有对特定模型数据的 SQL 语句。