[英]Audit.NET Entity Framework Core - Related Entities management
我正在開發 ASP.NET Core 3.1 web 應用程序。 我想在數據庫中保存數據時添加審計跟蹤/日志。
我從這個 SO answer中獲得靈感,開始在測試項目中使用 Audit.NET。
這是我的目標(類似於相關的 SO 線程):
AppAuditDbContext
幾乎完成;AppAuditDbContext
的反射完成;AppAuditDbContext
和DataAnnotations
的反射來完成; 此時,我可以 CRUD 一個獨立的審計實體,並在審計數據庫上檢索正確的審計。
但是,盡管我可以成功刪除父實體及其子實體並獲取父實體和子實體的審計數據,但對於這種情況,我無法弄清楚如何從數據庫中獲取分組的審計數據。
我嘗試使用 Audit.NET EntityFramework 的EntityFrameworkEvent.TransactionId
和EntityFrameworkEvent.AmbientTransactionId
,但它們在數據庫上都是null
。
這是我的 POCO
public interface IAuditableEntity
{
[NotMapped]
string AuditAction { get; set; }
[NotMapped]
string AuditTransactionId { get; set; }
[NotMapped]
string AuditAmbientTransactionId { get; set; }
}
public class Scope : IAuditableEntity
{
[Key]
public int Id {get;set;}
public string Name { get; set; }
public virtual ICollection<Job> Jobs { get; set; }
[NotMapped]
string AuditAction { get; set; }
[NotMapped]
string AuditTransactionId { get; set; }
[NotMapped]
string AuditAmbientTransactionId { get; set; }
}
public class Job : IAuditableEntity
{
[Key]
public int Id {get;set;}
public int ScopeId { get; set; }
public virtual Scope Scope { get; set; }
[StringLength(128)]
public string Name { get; set; }
[NotMapped]
public string AuditAction { get; set; }
[NotMapped]
public string AuditTransactionId { get; set; }
[NotMapped]
public string AuditAmbientTransactionId { get; set; }
}
這是我的 Audit.NET 配置(來自 Startup.cs)
public class Startup
{
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContext<ApplicationDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));
services.AddDbContext<AppAuditDbContext>(options =>
options.UseSqlServer(Configuration.GetConnectionString("AuditConnection")));
#region Audit.NET
var auditDbContextOptions = new DbContextOptionsBuilder<AppAuditDbContext>()
.UseSqlServer(Configuration.GetConnectionString("AuditConnection"))
.Options;
Audit.Core.Configuration.Setup()
.UseEntityFramework(x => x
.UseDbContext<AppAuditDbContext>(auditDbContextOptions)
.AuditTypeNameMapper(typeName =>
{
return typeName;
}).AuditEntityAction<IAuditableEntity>((ev, ent, auditEntity) =>
{
var entityFrameworkEvent = ev.GetEntityFrameworkEvent();
if (entityFrameworkEvent == null) return;
auditEntity.AuditTransactionId = entityFrameworkEvent.TransactionId;
auditEntity.AuditAmbientTransactionId = entityFrameworkEvent.AmbientTransactionId;
auditEntity.AuditAction = ent.Action;
}));
#endregion
services.AddControllersWithViews();
}
// other stuff..
}
這是經過審計的上下文。
[AuditDbContext(IncludeEntityObjects = true)]
public class ApplicationDbContext : AuditDbContext
{
public ApplicationDbContext([NotNullAttribute] DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
public DbSet<Scope> Scopes { get; set; }
public DbSet<Job> Jobs { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Scope>().ToTable("Scope");
modelBuilder.Entity<Job>().ToTable("Job");
}
public override int SaveChanges()
{
return base.SaveChanges();
}
public override async Task<int> SaveChangesAsync(CancellationToken cancellationToken = default)
{
return await base.SaveChangesAsync(cancellationToken);
}
}
這是范圍的刪除 controller 操作。
public class ScopeController : Controller
{
private readonly ApplicationDbContext _context;
public ScopeController(ApplicationDbContext context)
{
_context = context;
}
// Other controller actions...
// POST: Scope/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public async Task<IActionResult> DeleteConfirmed(int id)
{
var scope = await _context.Scopes.Include(s => s.Jobs).SingleOrDefaultAsync(w => w.Id == id);
// using _context.Scopes.FindAsync(id) instead does delete the children Jobs without auditing it
_context.Scopes.Remove(scope);
await _context.SaveChangesAsync().ConfigureAwait(false);
return RedirectToAction(nameof(Index));
}
}
這個 controller 操作從 EF 的角度來看是有效的。 它還審計父項和子項刪除操作,但我不知道如何將子項審計記錄與父項審計記錄相關聯我應該在代碼中的某處添加 AuditScope 嗎? 請問,我如何配置 Audit.NET 才能查詢審計數據庫以獲取分組的審計數據?
這是 ID #5 的 Scope 的審計跟蹤。
Audit_Scope 表
這是 ScopeId #5 的作業的審計跟蹤。
Audit_Job 表
鑒於提供的數據,假設我想讀取 Scope 的刪除審計(在本例中為 Audit_Scope 表中的 AuditId #9),包括對其子作業的刪除審計(在本例中為 Audit_Job 表中的 AuditId #10) . 我怎樣才能做到這一點?
謝謝,馬特奧
目前我剛剛向我的實體添加了一個自定義字段。 我在帶有 Guid 的自定義操作中重視它。
// EF AuditEventId per scope
Audit.Core.Configuration.AddCustomAction(ActionType.OnScopeCreated, scope =>
{
var id = Guid.NewGuid();
scope.SetCustomField("AuditScopeId", id);
});
這樣,與同一審計事件相關的Scope
和Job
表記錄將持有相同的AuditScopeId
值。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.