Вы не можете сделать это с вашим классом сущности по ряду причин.CreatedOn
может быть обработано по умолчанию, но для остальных требуются знания, которых у класса сущностей никогда не будет, например, HttpContext.User
или просто ли он был изменен или создан.
Вместо этого вам понадобитсячтобы встроить эту функциональность в ваш контекст.Во-первых, вам нужно, чтобы все ваши классы сущностей реализовали определенный интерфейс для наследования от определенного базового класса.В любом случае вы хотите добавить эти свойства к этому, чтобы вы могли быть уверены, что любой реализованный / производный класс будет обладать указанными свойствами.
Затем вы можете добавить приватный метод в свой контекстный класс, например:
private void PopulateAuditTrailProperties()
{
var httpContextAccessor = this.GetService<IHttpContextAccessor>();
var username = httpContextAccessor?.HttpContext.User.Identity.Name;
foreach (var entry in ChangeTracker.Entries<IEntity>().Where(x => x.State == EntityState.Added))
{
entry.Entity.CreatedOn = DateTimeOffset.UtcNow;
entry.Entity.CreatedBy = username;
}
foreach (var entry in ChangeTracker.Entries<IEntity>().Where(x => x.State == EntityState.Modified))
{
entry.Entity.ModifiedOn = DateTimeOffset.UtcNow;
entry.Entity.ModifiedBy = username;
}
}
Затем вам нужно переопределить SaveChanges
и SaveChangesAsync
в вашем контексте, чтобы каждый вызов вызывал этот метод перед сохранением:
public override int SaveChanges(bool acceptAllChangesOnSuccess)
{
PopulateAuditTrailProperties();
return base.SaveChanges(acceptAllChangesOnSuccess);
}
public override Task<int> SaveChangesAsync(bool acceptAllChangesOnSuccess, CancellationToken cancellationToken = default)
{
PopulateAuditTrailProperties();
return base.SaveChangesAsync(acceptAllChangesOnSuccess, cancellationToken);
}
Наконец, вынужно добавить пару вещей к вашему Startup.cs
:
services.AddDbContext<MyContext>(o =>
o.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"))
.UseInternalServiceProvider()); // Add this line
И:
services.AddHttpContextAccessor();