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 5.x and later, cannot use Change-tracking proxies with EntityFrameworkDataProvider

See original GitHub issue

Describe the bug Since EF Core 5.0, Microsoft has put built-in support for change-tracking proxies via the Microsoft.EntityFrameworkCore.Proxies package, as described here: https://docs.microsoft.com/en-us/ef/core/change-tracking/change-detection#change-tracking-proxies

When trying to use change-tracking proxies with the EntityFrameworkDataProvider, I get an exception on trying to save changes to the database because the object instance of the audit entity was created in Audit.NET using Activator.CreateInstance instead of using the DbContext’s CreateProxy. Specifically the exception is as follows:

System.InvalidOperationException: 'The entity type 'AuditLog' is configured to use the 'ChangingAndChangedNotifications' change tracking strategy, but does not implement the required 'INotifyPropertyChanging' interface. Implement 'INotifyPropertyChanging' on 'AuditLog' or use a different change tracking strategy.'

To Reproduce (This is just a pretty bare bones set of classes, which I hope should be enough to demonstrate the problem.)

public class AuditLog
{
    public int Id { get; set; }
    public DateTime DateTime { get; set; }
}
public class Test
{
    public int Id { get; set; }
    public string TestString { get; set; }
}
public class MyDbContext : AuditDbContext
{
    public DbSet<Test> Tests => this.Set<Test>();

    // Assume there is an OnConfiguring here that calls UseChangeTrackingProxies() on the optionsBuilder
}
class Program
{
    static void Main()
    {
        _ = Audit.Core.Configuration.Setup().UseEntityFramework(ef => ef.
            UseDbContext<MyDbContext>().
            AuditTypeMapper(t => typeof(AuditLog)).
            AuditEntityAction<AuditLog>((ev, ent, auditEntity) => auditEntity.DateTime = DateTime.Now).
            IgnoreMatchedProperties(true)
        );
        using var context = new MyDbContext();
        _ = context.Test.Add(context.CreateProxy<Test>(test => test.TestString = "Test"));
        _ = context.SaveChanges(); // <-- Exception happens when this is called
    }
}

Expected behavior Audit.NET’s EntityFrameworkDataProvider should detect that the DbContext uses change-tracking proxies and change how it creates the audit entity for the database.

Libraries (specify the Audit.NET extensions being used including version):

  • Audit.EntityFramework.Core: 19.0.0
  • Microsoft.EntityFrameworkCore.Proxies: 5.0.12 (I suspect that the type of database being used won’t matter)

Target .NET framework:

  • .NET 5.0 (but I suspect the framework won’t matter, what matters is if EF Core 5.x or later is being used)

Additional context When not using change-tracking proxies, everything works as expected.

Issue Analytics

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

github_iconTop GitHub Comments

1reaction
CyberBotXcommented, Nov 20, 2021

I can confirm when using AuditEntityCreator that things work perfectly as expected, thank you for making this update. 😄

1reaction
CyberBotXcommented, Nov 17, 2021

After I got to work, I thought about this a little, perhaps you could have 2 signatures for that factory mapper, one as you suggested which would work for the single-table audit but another that provides both the context and the audit entity type (from the audit type mapper). CreateProxy has an overload which is non-generic and takes the Type as an argument.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Change Detection and Notifications - EF Core
Detecting property and relationship changes using DetectChanges or notifications.
Read more >
Why is Entity Framework not generating proxy?
To get change tracking proxies, the basic rule is that your class must be public, non-abstract or non-sealed. Your class must also implement ......
Read more >
Should you use Entity Framework change-tracking proxies?
If you never mutate complex objects (which is, in my opinion, good practice) then they won't require DetectChanges, but by default EF assumes ......
Read more >
Entity Framework Core 5 - Pitfalls To Avoid and Ideas to Try
In this post, we'll look at some pitfalls and ideas EF Core users like ... We can opt-out of object tracking by using...
Read more >
What's New in EF Core 5 - Learn Entity Framework Core 7
EF Core 5.0 introduces the ToQueryString extension method, which will return the SQL that EF Core will generate when executing a LINQ query....
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