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.

EF Core value updates are not audited

See original GitHub issue

EntityFramework changes are not getting audited or detected.

I am using a dotnet project as a package to make any DB changes. ie the package houses the databaseContext (Persistence package) I use another .net project to trigger these database changes through repository methods.

The Persistence package is used by multiple projects. The database changes through this package are properly audited when running from other .net projects, but completely ignored when using from one .net project. The config I set up for both these projects is the same. Yet Audits are not triggered from this particular project.

My setup:

Persistence package (Common .net project that houses the databaseContext and is used as a package)

In the DBContext Class:

` [AuditDbContext(Mode = AuditOptionMode.OptIn, IncludeEntityObjects = false, AuditEventType = “EF”)] public class CWContext : DbContext { private readonly DbContextHelper _helper = new DbContextHelper(); private readonly IAuditDbContext _auditContext;

    public CWContext(string connectionString) : base(GetOptions(connectionString))
    {
        _auditContext = new DefaultAuditContext(this);
        _helper.SetConfig(_auditContext);
    }
    . . . 
    . . .
    
    public override async Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default(CancellationToken))
    {
        try
        {
            //return await base.SaveChangesAsync();
            return await _helper.SaveChangesAsync(_auditContext, () => base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken));
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }
    public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default(CancellationToken))
    {
        try
        {
            //return await base.SaveChangesAsync();
            return await _helper.SaveChangesAsync(_auditContext, () => base.SaveChangesAsync(cancellationToken));
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

    public override int SaveChanges()
    {
        try
        {
            //return base.SaveChanges();
            return _helper.SaveChanges(_auditContext, () => base.SaveChanges());
        }
        catch (Exception ex)
        {
            throw ex;
        }
    }

`

In the Entity class: [AuditInclude] public class Patient { . . .

CSPROJ: <Project Sdk="Microsoft.NET.Sdk"> <TargetFramework>net6.0</TargetFramework> . . . <ItemGroup> <PackageReference Include="Audit.EntityFramework.Core" Version="21.0.1" /> <PackageReference Include="EFCore.BulkExtensions" Version="6.0.1" /> <PackageReference Include="GitInfo" Version="2.2.0" /> <PackageReference Include="Microsoft.EntityFrameworkCore" Version="6.0.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="6.0.1" /> <PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="6.0.1" /> <PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="6.0.0" PrivateAssets="all" /> </ItemGroup>

In the .net Project that uses this Persistence package
(Project A-NotWorking)

In the ProjectStartup code:

       var app = builder.Build();
       . . .
        AuditLogsSetup.SetupAuditConfigs();
       app.Run();

}

The AuditLogsSetup static class: (Moving the contents of the static method directly up to the startup code didn’t work either)

public static class AuditLogsSetup { ////////////////////// I am using a custom data provider to write logs into ES from kinesis firehose here in other projects, but here, the default File Provider is also not working ///////////////////////////////// public static void SetupAuditConfigs() { Audit.Core.Configuration.Setup() .UseFileLogProvider(_ => _ .Directory(@“C:\Logs\AuditLogs”) .FilenameBuilder(ev => $“{ev.StartDate:yyyyMMddHHmmssffff}_{ev.EventType}.json”)); } }

CSPROJ:

<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
	<TargetFramework>net6.0</TargetFramework>
    . . . 
    
<ItemGroup>
	<PackageReference Include="Audit.EntityFramework.Core" Version="21.0.1" />
	<PackageReference Include="AWSSDK.KinesisFirehose" Version="3.7.101.113" />
            . . .
	<PackageReference Include="GitInfo" Version="2.2.0" />
	<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="6.0.3" />
	<PackageReference Include="Microsoft.AspNetCore.DataProtection.StackExchangeRedis" Version="6.0.4" />
	<PackageReference Include="Microsoft.Extensions.Caching.StackExchangeRedis" Version="6.0.4" />
	<PackageReference Include="Microsoft.Extensions.Http" Version="6.0.0" />
	<PackageReference Include="Microsoft.Extensions.Http.Polly" Version="6.0.0" />
	<PackageReference Include="Polly.Contrib.WaitAndRetry" Version="1.1.1" />
	<PackageReference Include="Serilog.AspNetCore" Version="4.1.0" />
	<PackageReference Include="Swashbuckle.AspNetCore" Version="6.2.3" />
	<PackageReference Include="System.Diagnostics.DiagnosticSource" Version="7.0.2" />
</ItemGroup>

Am I missing configuring something here?

Issue Analytics

  • State:closed
  • Created 3 months ago
  • Comments:13 (8 by maintainers)

github_iconTop GitHub Comments

1reaction
thepirat000commented, Jun 25, 2023

I didn’t find any official documentation stating so, but I think BulkUpdate cannot be intercepted in any way.

https://www.milanjovanovic.tech/blog/how-to-use-the-new-bulk-update-feature-in-ef-core-7

0reactions
thepirat000commented, Jul 7, 2023

You could do that, but you should call _auditContext.ReloadDatabaseValues = true AFTER calling _helper.SetConfig(), otherwise it will be overridden by the default configuration:

public MyContext(string connectionString) : base(GetOptions(connectionString))
{
    _auditContext = new DefaultAuditContext(this);
    _helper.SetConfig(_auditContext);
    _auditContext.ReloadDatabaseValues = true;
}

But the recommended way to set the configuration globally is by using the fluent API, for example:

Audit.EntityFramework.Configuration.Setup()
    .ForAnyContext(cfg => cfg.ReloadDatabaseValues());

Or:

Audit.EntityFramework.Configuration.Setup()
    .ForContext<MyContext>(cfg => cfg.ReloadDatabaseValues());

Also, I’ve just realized I didn’t add a property to the AuditDbContextAttribute, but will do it for the next release.

So, you will be able to set the configuration like this:

[AuditDbContext(ReloadDatabaseValues = true, Mode = AuditOptionMode.OptIn, IncludeEntityObjects = false, AuditEventType = "EF")]
public class MyContext : DbContext
{
   ...
}
Read more comments on GitHub >

github_iconTop Results From Across the Web

audit.net - Entity Framework Core updating unchanged fields
My goal is to capture only actual changes to the record, but it's capturing everything as change, even if the old and new...
Read more >
How to set up auditing in Entity Framework Core
In Entity Framework, entity auditing can easily be configured by overriding the SaveChangesAsync method.
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 >
Audit in Entity Framework Plus (EF Plus)
EF+ Audit easily tracks changes, exclude/include entity or property and auto save audit entries in the database.
Read more >
EF Core - Audit Fields - Track Created By and Last Updated ...
In this post, we will implement audit tracking so that the audit fields are automatically added onto our entities and EF Core automatically ......
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