我参考的网站内容:
https://entityframework-plus.net/ef-core-audit-customization
https://entityframework-plus.net/ef-core-audit-autosave
https://csharp.hotexamples.com/examples/Z.EntityFramework.Plus/Audit/-/php-audit-class-examples.html
https://entityframework-plus.net/audit
https://stackoverflow.com/questions/58711828/how-to-use-code-first-with-entityframework-plus-audit-feature
在构造器中加入:
public DbSet<AuditEntry> AuditEntries { get; set; } public DbSet<AuditEntryProperty> AuditEntryProperties { get; set; } public DataContext() { AuditManager.DefaultConfiguration.AutoSavePreAction = (context, audit) => AuditEntries.AddRange(audit.Entries); } public DataContext(CS cs) : base(cs) { AuditManager.DefaultConfiguration.AutoSavePreAction = (context, audit) => AuditEntries.AddRange(audit.Entries); }
然后重写SaveChanges 和 SaveChangesAsync
public override int SaveChanges() { var audit = new Audit(); audit.PreSaveChanges(this); var rowAffecteds = base.SaveChanges(); audit.PostSaveChanges(); var entries = audit.Entries; if (audit.Configuration.AutoSavePreAction != null && entries.FirstOrDefault().EntitySetName != "BaseActionLogs") { audit.Configuration.AutoSavePreAction(this, audit); base.SaveChanges(); } return rowAffecteds; } public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default) { var audit = new Audit(); audit.PreSaveChanges(this); var rowAffecteds = await base.SaveChangesAsync(cancellationToken).ConfigureAwait(false); audit.PostSaveChanges(); if (audit.Configuration.AutoSavePreAction != null) { audit.Configuration.AutoSavePreAction(this, audit); await base.SaveChangesAsync(cancellationToken).ConfigureAwait(false); } return rowAffecteds; }
其实以上的Audit也可以用原始的方法实现:
public override int SaveChanges()
{
var changes = this.ChangeTracker.Entries().Where(x => x.State == EntityState.Added ||
x.State == EntityState.Modified ||
x.State == EntityState.Deleted);
foreach (var change in changes)
{
if (change.State == EntityState.Added)
{
// Log Added
}
else if (change.State == EntityState.Modified)
{
// Log Modified
var originalValues = change.OriginalValues;
var currentValues = change.CurrentValues;
foreach (var prop in change.OriginalValues.Properties)
{
var original = originalValues[prop.Name];
var current = currentValues[prop.Name];
if (!Equals(original, current))
{
// log propertyName: original --> current
}
}
}
else if (change.State == EntityState.Deleted)
{
// log deleted
}
}
return base.SaveChanges();
}
Database Script
https://entityframework-plus.net/ef-core-audit-autosave
CREATE TABLE [dbo].[AuditEntries] ( [AuditEntryID] [int] NOT NULL IDENTITY, [EntitySetName] [nvarchar](255), [EntityTypeName] [nvarchar](255), [State] [int] NOT NULL, [StateName] [nvarchar](255), [CreatedBy] [nvarchar](255), [CreatedDate] [datetime] NOT NULL, CONSTRAINT [PK_dbo.AuditEntries] PRIMARY KEY ([AuditEntryID]) ) GO CREATE TABLE [dbo].[AuditEntryProperties] ( [AuditEntryPropertyID] [int] NOT NULL IDENTITY, [AuditEntryID] [int] NOT NULL, [RelationName] [nvarchar](255), [PropertyName] [nvarchar](255), [OldValue] [nvarchar](max), [NewValue] [nvarchar](max), CONSTRAINT [PK_dbo.AuditEntryProperties] PRIMARY KEY ([AuditEntryPropertyID]) ) GO CREATE INDEX [IX_AuditEntryID] ON [dbo].[AuditEntryProperties]([AuditEntryID]) GO ALTER TABLE [dbo].[AuditEntryProperties] ADD CONSTRAINT [FK_dbo.AuditEntryProperties_dbo.AuditEntries_AuditEntryID] FOREIGN KEY ([AuditEntryID]) REFERENCES [dbo].[AuditEntries] ([AuditEntryID]) ON DELETE CASCADE GO
标签:audit,dbo,AuditEntryID,EF,State,开源,plus,var,nvarchar From: https://www.cnblogs.com/axblog/p/17768066.html