是否可以拦截 READ 操作?

use*_*430 6 c# entity-framework-core

在 Entity Framework Core 中,您可以根据不同的状态重写SaveChanges/SaveChangesAsync方法,例如:或或,您可以创建一些有关何时以及由谁创建、修改或删除某些记录的审核解决方案。您可以保存操作前后实体的状态。一切都在这里完美!DbContextEntityState.AddedEntityState.ModifiedEntityState.Deleted

我们可以对读取/查询/选择/查看操作执行类似的操作吗?

Ste*_*lan 6

我挖了一下,发现实际执行IQueryable是由EntityQueryProvider : IAsyncQueryProvider, IQueryProvider.

所以...您覆盖默认值EntityQueryProvider来进行日志记录:

   public class LoggingQueryProvider : EntityQueryProvider
    {
        public LoggingQueryProvider(IQueryCompiler queryCompiler) : base(queryCompiler) { }

        public override object Execute(Expression expression)
        {
            var result = base.Execute(expression);
            //log
            return result;
        }
        public override TResult Execute<TResult>(Expression expression)
        {
            var result = base.Execute<TResult>(expression);
            //log
            return result;
        }
        public override IAsyncEnumerable<TResult> ExecuteAsync<TResult>(Expression expression)
        {
            var result = base.ExecuteAsync<TResult>(expression);
            //log
            return result;
        }
        public override Task<TResult> ExecuteAsync<TResult>(Expression expression, CancellationToken cancellationToken)
        {
            var result = base.ExecuteAsync<TResult>(expression, cancellationToken);
            //log
            return result;
        }
    }
Run Code Online (Sandbox Code Playgroud)

并且在配置 DbContext 时注册它StartUp.ConfigureServices(IServiceCollection services)

    services.AddDbContext<XPContext>(builder =>
        builder
        .UseSqlServer(Configuration["TryDBConnectionString"])
        .ReplaceService<IAsyncQueryProvider, LoggingQueryProvider>()
    );
Run Code Online (Sandbox Code Playgroud)

这不是很直接,但您应该能够从表达式中获取一些信息,例如实体类型,并且您显然可以访问实际结果。对于异步方法来说,事情看起来有点复杂,但是......