Is it possible to intercept the READ action?

In the core of the Entity Framework, you can override the SaveChanges/ SaveChangesAsyncin method DbContextand based on different states, such as: EntityState.Addedor EntityState.Modifiedor EntityState.Deleted, you can create a solution to check when and who created, modified or deleted certain records. You can save the state of the object before and after the action. All the good things work fine here!

Is it possible to do something similar for read / query / select / view operations?

+4
source share
3 answers

I dug up a bit and found that the actual execution IQueryableis done using 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;
        }
    }

DbContext StartUp.ConfigureServices(IServiceCollection services)

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

, , , , , . , ...

+2

SaveChanges() , , Dispose().

, dbContext, , , EntityState.Unchanged.

, - DbContext , id , ChangeTracker , DbContext .

- :

public override void Dispose()
{
    var unchanged = ChangeTracker.Entries()
          .Where(x => x.EntityState == EntityState.Unchanged);

    // log your unchanged entries here

    base.Dispose();
 }

, / , , ,

0

I suggest keeping a journal at a higher level. For example, if you use WebApi, you can go to the OWIN pipeline level, thereby registering information requests.
The logging below ends with a second guessing and iterating over data that is ugly and ends up contributing to inefficiency.

0
source

Source: https://habr.com/ru/post/1687954/


All Articles