question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

Tracking Raw Sql Queries in Audit.EntityFramework.Core

See original GitHub issue

Hello,

I just implemented Audit.NET and I am using the Audit.EntityFramework.Core library to track entity changes.

I noticed that any calls to SaveChangesAsync is tracked just as stated. The issue is any query executed using DbContext.Database.ExecuteSqlRawAsync() is not tracked.

Is there a way to track these kind of changes?

Thanks.

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:10 (6 by maintainers)

github_iconTop GitHub Comments

1reaction
thepirat000commented, Sep 7, 2021

A new command interceptor was provided that logs raw SQL queries, for EF Core 3.0 and EF Core 5.0 starting on version 18.1.5

More information on the readme here

So you could attach the command interceptor with:

public class MyContext : DbContext
{
    protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.AddInterceptors(new AuditCommandInterceptor());
    }
}
1reaction
thepirat000commented, Sep 3, 2021

For EF Core 5, I think one option is to use a DbCommandInterceptor that intercepts the ExecuteSqlRaw calls, but I’m afraid it will also intercept any other commands issued by EF internally.

Check this: https://docs.microsoft.com/en-us/ef/core/logging-events-diagnostics/

For example:

public class AuditCommandInterceptor : DbCommandInterceptor
{
    public override int NonQueryExecuted(DbCommand command, CommandExecutedEventData eventData, int result)
    {
        var parameters = new Dictionary<string, object>();
        foreach (DbParameter p in command.Parameters)
            parameters.Add(p.ParameterName, p.Value);
        using var scope = AuditScope.Create(new AuditScopeOptions()
        {
            EventType = "NonQueryExecuted:Success",
            IsCreateAndSave = true,
            ExtraFields = new
            {
                Command = new 
                {
                    Duration = (int)eventData.Duration.TotalMilliseconds,
                    Text = command.CommandText,
                    Params = parameters,
                },
                ConnectionId = eventData.ConnectionId,
                Result = result
            }
        });
        return base.NonQueryExecuted(command, eventData, result);
    }

    public override void CommandFailed(DbCommand command, CommandErrorEventData eventData)
    {
        var parameters = new Dictionary<string, object>();
        foreach (DbParameter p in command.Parameters)
            parameters.Add(p.ParameterName, p.Value);
        using var scope = AuditScope.Create(new AuditScopeOptions()
        {
            EventType = "NonQueryExecuted:Failure",
            IsCreateAndSave = true,
            ExtraFields = new
            {
                Command = new
                {
                    Duration = (int)eventData.Duration.TotalMilliseconds,
                    Text = command.CommandText,
                    Params = parameters,
                },
                ConnectionId = eventData.ConnectionId,
                Error = eventData.Exception.ToString()
            }
        });
        base.CommandFailed(command, eventData);
    }
}

Note you should also implement the Async version of the methods: NonQueryExecutedAsync and CommandFailedAsync.

Then you can add the interceptor when creating your DbContext, for example:

using (var ctx = new MyContext(new DbContextOptionsBuilder<MyContext>()
    .UseSqlServer("...")
    .AddInterceptors(new AuditCommandInterceptor())
    .Options))
{
    var result = ctx.Database.ExecuteSqlRaw("INSERT INTO ITEMS (Name) VALUES ({0})", "test");
    //...
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

Executing Raw SQL Queries using Entity Framework Core
Entity Framework Core provides mechanisms for executing raw SQL queries including stored procedures directly against the database.
Read more >
Audit trail with Entity Framework Core - sql server
If you plan to store the audit logs in the same database as the audited entities, you can use the EntityFrameworkDataProvider . Use...
Read more >
Audit Trail Implementation in ASP.NET Core with Entity ...
Well, it's a handy technique to track changes that are done by your logged-in users. Ever wondered who had updated the value of...
Read more >
Overview of logging and interception - EF Core
Entity Framework Core (EF Core) contains several mechanisms for generating logs, responding to events, and obtaining diagnostics.
Read more >
How To Track Entity Changes With EF Core | Audit Logging
However, with EF Core there is an easy way to implement entity change tracking as ... How To Apply Global Filters With EF...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found